2 * Copyright (c) 2006 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 /* Supported long branch types */
37 /* Supported predicates */
41 /* Supported variations */
45 #if TYPE == 0 || PRED == 0 || VAR == 0
46 #error Define TYPE, PRED and/or VAR
50 unsigned char bytes[16];
55 * Machine code of a bundle containing a long branch. The predicate of the
56 * long branch is the result of the compare in the first slot.
57 * The assembly of the bundle is:
59 * cmp.eq p0,p15= <PREDICATE>,r0
60 * (p15) brl.few <TARGET> ;;
62 * the predicate is written to bit 18:1
63 * The branch target is written to bits 100:20, 48:39 and 123:1
65 unsigned char mc_brl_cond[16] = {
66 0x05, 0x00, 0x00, 0x00, 0x0f, 0x39,
67 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
68 0x00, 0x00, 0x00, 0xc0
72 * Machine code of the epilogue of a typical function returning an integer.
73 * The assembly of the epilogue is:
76 * addl r8 = <RETVAL>, r0
77 * br.ret.sptk.few b0 ;;
79 * The return value is written to bits 59:7, 73:9, 68:5, and 82:1.
81 unsigned char mc_epilogue[16] = {
82 0x11, 0x00, 0x00, 0x00, 0x01, 0x00,
83 0x80, 0x00, 0x00, 0x00, 0x48, 0x80,
84 0x00, 0x00, 0x84, 0x00
88 mc_patch(union bundle *b, unsigned long val, int start, int len)
96 run = ((len > (8 - bit)) ? (8 - bit) : len);
97 mask = (1UL << run) - 1UL;
98 b->bytes[byte] |= (val & mask) << bit;
107 assemble_brl_cond(union bundle *b, int pred, unsigned long tgt)
111 iprel = tgt - (unsigned long)b;
112 memcpy(b->bytes, mc_brl_cond, sizeof(mc_brl_cond));
113 mc_patch(b, pred ? 1 : 0, 18, 1);
114 mc_patch(b, iprel >> 4, 100, 20);
115 mc_patch(b, iprel >> 24, 48, 39);
116 mc_patch(b, iprel >> 63, 123, 1);
120 assemble_epilogue(union bundle *b, int retval)
122 memcpy(b->bytes, mc_epilogue, sizeof(mc_epilogue));
123 mc_patch(b, retval, 59, 7);
124 mc_patch(b, retval >> 7, 73, 9);
125 mc_patch(b, retval >> 16, 68, 5);
126 mc_patch(b, retval >> 21, 82, 1);
132 asm("mov b6 = %0; br.sptk b6;;" :: "r"(addr));
137 test_cond(int pred, union bundle *src, union bundle *dst)
139 assemble_epilogue(dst, pred ? 0 : 2);
140 assemble_brl_cond(src, pred ? 1 : 0, (unsigned long)dst);
141 assemble_epilogue(src + 1, !pred ? 0 : 2);
148 static union bundle blob_low[2];
149 union bundle *blob_high;
152 addr = (void *)0x7FFFFFFF00000000L;
153 blob_high = mmap(addr, 32, PROT_EXEC | PROT_READ | PROT_WRITE,
155 if (blob_high != addr)
156 printf("NOTICE: blob_high is at %p, not at %p\n", blob_high,
160 return (test_call(blob_high, blob_low));
163 return (test_cond(PRED - 1, blob_low, blob_high));
164 #elif VAR == Backward
165 return (test_cond(PRED - 1, blob_high, blob_low));