Statistics
| Branch: | Revision:

root / tcg / hppa / tcg-target.c @ 91493631

History | View | Annotate | Download (51.8 kB)

1 f54b3f92 aurel32
/*
2 f54b3f92 aurel32
 * Tiny Code Generator for QEMU
3 f54b3f92 aurel32
 *
4 f54b3f92 aurel32
 * Copyright (c) 2008 Fabrice Bellard
5 f54b3f92 aurel32
 *
6 f54b3f92 aurel32
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 f54b3f92 aurel32
 * of this software and associated documentation files (the "Software"), to deal
8 f54b3f92 aurel32
 * in the Software without restriction, including without limitation the rights
9 f54b3f92 aurel32
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 f54b3f92 aurel32
 * copies of the Software, and to permit persons to whom the Software is
11 f54b3f92 aurel32
 * furnished to do so, subject to the following conditions:
12 f54b3f92 aurel32
 *
13 f54b3f92 aurel32
 * The above copyright notice and this permission notice shall be included in
14 f54b3f92 aurel32
 * all copies or substantial portions of the Software.
15 f54b3f92 aurel32
 *
16 f54b3f92 aurel32
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 f54b3f92 aurel32
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 f54b3f92 aurel32
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 f54b3f92 aurel32
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 f54b3f92 aurel32
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 f54b3f92 aurel32
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 f54b3f92 aurel32
 * THE SOFTWARE.
23 f54b3f92 aurel32
 */
24 f54b3f92 aurel32
25 d4a9eb1f blueswir1
#ifndef NDEBUG
26 f54b3f92 aurel32
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
27 fd76e73a Richard Henderson
    "%r0", "%r1", "%rp", "%r3", "%r4", "%r5", "%r6", "%r7",
28 fd76e73a Richard Henderson
    "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
29 fd76e73a Richard Henderson
    "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
30 fd76e73a Richard Henderson
    "%r24", "%r25", "%r26", "%dp", "%ret0", "%ret1", "%sp", "%r31",
31 f54b3f92 aurel32
};
32 d4a9eb1f blueswir1
#endif
33 f54b3f92 aurel32
34 fd76e73a Richard Henderson
/* This is an 8 byte temp slot in the stack frame.  */
35 fd76e73a Richard Henderson
#define STACK_TEMP_OFS -16
36 fd76e73a Richard Henderson
37 fd76e73a Richard Henderson
#ifndef GUEST_BASE
38 fd76e73a Richard Henderson
#define GUEST_BASE 0
39 fd76e73a Richard Henderson
#endif
40 fd76e73a Richard Henderson
41 fd76e73a Richard Henderson
#ifdef CONFIG_USE_GUEST_BASE
42 fd76e73a Richard Henderson
#define TCG_GUEST_BASE_REG TCG_REG_R16
43 fd76e73a Richard Henderson
#else
44 fd76e73a Richard Henderson
#define TCG_GUEST_BASE_REG TCG_REG_R0
45 fd76e73a Richard Henderson
#endif
46 fd76e73a Richard Henderson
47 f54b3f92 aurel32
static const int tcg_target_reg_alloc_order[] = {
48 f54b3f92 aurel32
    TCG_REG_R4,
49 f54b3f92 aurel32
    TCG_REG_R5,
50 f54b3f92 aurel32
    TCG_REG_R6,
51 f54b3f92 aurel32
    TCG_REG_R7,
52 f54b3f92 aurel32
    TCG_REG_R8,
53 f54b3f92 aurel32
    TCG_REG_R9,
54 f54b3f92 aurel32
    TCG_REG_R10,
55 f54b3f92 aurel32
    TCG_REG_R11,
56 f54b3f92 aurel32
    TCG_REG_R12,
57 f54b3f92 aurel32
    TCG_REG_R13,
58 f54b3f92 aurel32
59 f54b3f92 aurel32
    TCG_REG_R17,
60 f54b3f92 aurel32
    TCG_REG_R14,
61 f54b3f92 aurel32
    TCG_REG_R15,
62 f54b3f92 aurel32
    TCG_REG_R16,
63 fd76e73a Richard Henderson
64 fd76e73a Richard Henderson
    TCG_REG_R26,
65 fd76e73a Richard Henderson
    TCG_REG_R25,
66 fd76e73a Richard Henderson
    TCG_REG_R24,
67 fd76e73a Richard Henderson
    TCG_REG_R23,
68 fd76e73a Richard Henderson
69 fd76e73a Richard Henderson
    TCG_REG_RET0,
70 fd76e73a Richard Henderson
    TCG_REG_RET1,
71 f54b3f92 aurel32
};
72 f54b3f92 aurel32
73 f54b3f92 aurel32
static const int tcg_target_call_iarg_regs[4] = {
74 f54b3f92 aurel32
    TCG_REG_R26,
75 f54b3f92 aurel32
    TCG_REG_R25,
76 f54b3f92 aurel32
    TCG_REG_R24,
77 f54b3f92 aurel32
    TCG_REG_R23,
78 f54b3f92 aurel32
};
79 f54b3f92 aurel32
80 f54b3f92 aurel32
static const int tcg_target_call_oarg_regs[2] = {
81 f54b3f92 aurel32
    TCG_REG_RET0,
82 f54b3f92 aurel32
    TCG_REG_RET1,
83 f54b3f92 aurel32
};
84 f54b3f92 aurel32
85 fd76e73a Richard Henderson
/* True iff val fits a signed field of width BITS.  */
86 fd76e73a Richard Henderson
static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
87 fd76e73a Richard Henderson
{
88 fd76e73a Richard Henderson
    return (val << ((sizeof(tcg_target_long) * 8 - bits))
89 fd76e73a Richard Henderson
            >> (sizeof(tcg_target_long) * 8 - bits)) == val;
90 fd76e73a Richard Henderson
}
91 fd76e73a Richard Henderson
92 fd76e73a Richard Henderson
/* True iff depi can be used to compute (reg | MASK).
93 fd76e73a Richard Henderson
   Accept a bit pattern like:
94 fd76e73a Richard Henderson
      0....01....1
95 fd76e73a Richard Henderson
      1....10....0
96 fd76e73a Richard Henderson
      0..01..10..0
97 fd76e73a Richard Henderson
   Copied from gcc sources.  */
98 fd76e73a Richard Henderson
static inline int or_mask_p(tcg_target_ulong mask)
99 fd76e73a Richard Henderson
{
100 fd76e73a Richard Henderson
    mask += mask & -mask;
101 fd76e73a Richard Henderson
    return (mask & (mask - 1)) == 0;
102 fd76e73a Richard Henderson
}
103 fd76e73a Richard Henderson
104 fd76e73a Richard Henderson
/* True iff depi or extru can be used to compute (reg & mask).
105 fd76e73a Richard Henderson
   Accept a bit pattern like these:
106 fd76e73a Richard Henderson
      0....01....1
107 fd76e73a Richard Henderson
      1....10....0
108 fd76e73a Richard Henderson
      1..10..01..1
109 fd76e73a Richard Henderson
   Copied from gcc sources.  */
110 fd76e73a Richard Henderson
static inline int and_mask_p(tcg_target_ulong mask)
111 fd76e73a Richard Henderson
{
112 fd76e73a Richard Henderson
    return or_mask_p(~mask);
113 fd76e73a Richard Henderson
}
114 fd76e73a Richard Henderson
115 fd76e73a Richard Henderson
static int low_sign_ext(int val, int len)
116 fd76e73a Richard Henderson
{
117 fd76e73a Richard Henderson
    return (((val << 1) & ~(-1u << len)) | ((val >> (len - 1)) & 1));
118 fd76e73a Richard Henderson
}
119 fd76e73a Richard Henderson
120 fd76e73a Richard Henderson
static int reassemble_12(int as12)
121 fd76e73a Richard Henderson
{
122 fd76e73a Richard Henderson
    return (((as12 & 0x800) >> 11) |
123 fd76e73a Richard Henderson
            ((as12 & 0x400) >> 8) |
124 fd76e73a Richard Henderson
            ((as12 & 0x3ff) << 3));
125 fd76e73a Richard Henderson
}
126 fd76e73a Richard Henderson
127 fd76e73a Richard Henderson
static int reassemble_17(int as17)
128 fd76e73a Richard Henderson
{
129 fd76e73a Richard Henderson
    return (((as17 & 0x10000) >> 16) |
130 fd76e73a Richard Henderson
            ((as17 & 0x0f800) << 5) |
131 fd76e73a Richard Henderson
            ((as17 & 0x00400) >> 8) |
132 fd76e73a Richard Henderson
            ((as17 & 0x003ff) << 3));
133 fd76e73a Richard Henderson
}
134 fd76e73a Richard Henderson
135 fd76e73a Richard Henderson
static int reassemble_21(int as21)
136 fd76e73a Richard Henderson
{
137 fd76e73a Richard Henderson
    return (((as21 & 0x100000) >> 20) |
138 fd76e73a Richard Henderson
            ((as21 & 0x0ffe00) >> 8) |
139 fd76e73a Richard Henderson
            ((as21 & 0x000180) << 7) |
140 fd76e73a Richard Henderson
            ((as21 & 0x00007c) << 14) |
141 fd76e73a Richard Henderson
            ((as21 & 0x000003) << 12));
142 fd76e73a Richard Henderson
}
143 fd76e73a Richard Henderson
144 fd76e73a Richard Henderson
/* ??? Bizzarely, there is no PCREL12F relocation type.  I guess all
145 fd76e73a Richard Henderson
   such relocations are simply fully handled by the assembler.  */
146 fd76e73a Richard Henderson
#define R_PARISC_PCREL12F  R_PARISC_NONE
147 fd76e73a Richard Henderson
148 f54b3f92 aurel32
static void patch_reloc(uint8_t *code_ptr, int type,
149 f54b3f92 aurel32
                        tcg_target_long value, tcg_target_long addend)
150 f54b3f92 aurel32
{
151 fd76e73a Richard Henderson
    uint32_t *insn_ptr = (uint32_t *)code_ptr;
152 fd76e73a Richard Henderson
    uint32_t insn = *insn_ptr;
153 fd76e73a Richard Henderson
    tcg_target_long pcrel;
154 fd76e73a Richard Henderson
155 fd76e73a Richard Henderson
    value += addend;
156 fd76e73a Richard Henderson
    pcrel = (value - ((tcg_target_long)code_ptr + 8)) >> 2;
157 fd76e73a Richard Henderson
158 f54b3f92 aurel32
    switch (type) {
159 fd76e73a Richard Henderson
    case R_PARISC_PCREL12F:
160 fd76e73a Richard Henderson
        assert(check_fit_tl(pcrel, 12));
161 fd76e73a Richard Henderson
        /* ??? We assume all patches are forward.  See tcg_out_brcond
162 fd76e73a Richard Henderson
           re setting the NUL bit on the branch and eliding the nop.  */
163 fd76e73a Richard Henderson
        assert(pcrel >= 0);
164 fd76e73a Richard Henderson
        insn &= ~0x1ffdu;
165 fd76e73a Richard Henderson
        insn |= reassemble_12(pcrel);
166 fd76e73a Richard Henderson
        break;
167 f54b3f92 aurel32
    case R_PARISC_PCREL17F:
168 fd76e73a Richard Henderson
        assert(check_fit_tl(pcrel, 17));
169 fd76e73a Richard Henderson
        insn &= ~0x1f1ffdu;
170 fd76e73a Richard Henderson
        insn |= reassemble_17(pcrel);
171 f54b3f92 aurel32
        break;
172 f54b3f92 aurel32
    default:
173 f54b3f92 aurel32
        tcg_abort();
174 f54b3f92 aurel32
    }
175 fd76e73a Richard Henderson
176 fd76e73a Richard Henderson
    *insn_ptr = insn;
177 f54b3f92 aurel32
}
178 f54b3f92 aurel32
179 f54b3f92 aurel32
/* maximum number of register used for input function arguments */
180 f54b3f92 aurel32
static inline int tcg_target_get_call_iarg_regs_count(int flags)
181 f54b3f92 aurel32
{
182 f54b3f92 aurel32
    return 4;
183 f54b3f92 aurel32
}
184 f54b3f92 aurel32
185 f54b3f92 aurel32
/* parse target specific constraints */
186 d4a9eb1f blueswir1
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
187 f54b3f92 aurel32
{
188 f54b3f92 aurel32
    const char *ct_str;
189 f54b3f92 aurel32
190 f54b3f92 aurel32
    ct_str = *pct_str;
191 f54b3f92 aurel32
    switch (ct_str[0]) {
192 f54b3f92 aurel32
    case 'r':
193 f54b3f92 aurel32
        ct->ct |= TCG_CT_REG;
194 f54b3f92 aurel32
        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
195 f54b3f92 aurel32
        break;
196 f54b3f92 aurel32
    case 'L': /* qemu_ld/st constraint */
197 f54b3f92 aurel32
        ct->ct |= TCG_CT_REG;
198 f54b3f92 aurel32
        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
199 f54b3f92 aurel32
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R26);
200 f54b3f92 aurel32
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R25);
201 f54b3f92 aurel32
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R24);
202 f54b3f92 aurel32
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R23);
203 f54b3f92 aurel32
        break;
204 fd76e73a Richard Henderson
    case 'Z':
205 fd76e73a Richard Henderson
        ct->ct |= TCG_CT_CONST_0;
206 fd76e73a Richard Henderson
        break;
207 fd76e73a Richard Henderson
    case 'I':
208 fd76e73a Richard Henderson
        ct->ct |= TCG_CT_CONST_S11;
209 fd76e73a Richard Henderson
        break;
210 fd76e73a Richard Henderson
    case 'J':
211 fd76e73a Richard Henderson
        ct->ct |= TCG_CT_CONST_S5;
212 fd76e73a Richard Henderson
        break;
213 91493631 Richard Henderson
    case 'K':
214 91493631 Richard Henderson
        ct->ct |= TCG_CT_CONST_MS11;
215 91493631 Richard Henderson
        break;
216 f54b3f92 aurel32
    default:
217 f54b3f92 aurel32
        return -1;
218 f54b3f92 aurel32
    }
219 f54b3f92 aurel32
    ct_str++;
220 f54b3f92 aurel32
    *pct_str = ct_str;
221 f54b3f92 aurel32
    return 0;
222 f54b3f92 aurel32
}
223 f54b3f92 aurel32
224 f54b3f92 aurel32
/* test if a constant matches the constraint */
225 fd76e73a Richard Henderson
static int tcg_target_const_match(tcg_target_long val,
226 fd76e73a Richard Henderson
                                  const TCGArgConstraint *arg_ct)
227 f54b3f92 aurel32
{
228 fd76e73a Richard Henderson
    int ct = arg_ct->ct;
229 fd76e73a Richard Henderson
    if (ct & TCG_CT_CONST) {
230 fd76e73a Richard Henderson
        return 1;
231 fd76e73a Richard Henderson
    } else if (ct & TCG_CT_CONST_0) {
232 fd76e73a Richard Henderson
        return val == 0;
233 fd76e73a Richard Henderson
    } else if (ct & TCG_CT_CONST_S5) {
234 fd76e73a Richard Henderson
        return check_fit_tl(val, 5);
235 fd76e73a Richard Henderson
    } else if (ct & TCG_CT_CONST_S11) {
236 fd76e73a Richard Henderson
        return check_fit_tl(val, 11);
237 91493631 Richard Henderson
    } else if (ct & TCG_CT_CONST_MS11) {
238 91493631 Richard Henderson
        return check_fit_tl(-val, 11);
239 fd76e73a Richard Henderson
    }
240 f54b3f92 aurel32
    return 0;
241 f54b3f92 aurel32
}
242 f54b3f92 aurel32
243 f54b3f92 aurel32
#define INSN_OP(x)       ((x) << 26)
244 f54b3f92 aurel32
#define INSN_EXT3BR(x)   ((x) << 13)
245 f54b3f92 aurel32
#define INSN_EXT3SH(x)   ((x) << 10)
246 f54b3f92 aurel32
#define INSN_EXT4(x)     ((x) << 6)
247 f54b3f92 aurel32
#define INSN_EXT5(x)     (x)
248 f54b3f92 aurel32
#define INSN_EXT6(x)     ((x) << 6)
249 f54b3f92 aurel32
#define INSN_EXT7(x)     ((x) << 6)
250 f54b3f92 aurel32
#define INSN_EXT8A(x)    ((x) << 6)
251 f54b3f92 aurel32
#define INSN_EXT8B(x)    ((x) << 5)
252 f54b3f92 aurel32
#define INSN_T(x)        (x)
253 f54b3f92 aurel32
#define INSN_R1(x)       ((x) << 16)
254 f54b3f92 aurel32
#define INSN_R2(x)       ((x) << 21)
255 f54b3f92 aurel32
#define INSN_DEP_LEN(x)  (32 - (x))
256 f54b3f92 aurel32
#define INSN_SHDEP_CP(x) ((31 - (x)) << 5)
257 f54b3f92 aurel32
#define INSN_SHDEP_P(x)  ((x) << 5)
258 f54b3f92 aurel32
#define INSN_COND(x)     ((x) << 13)
259 fd76e73a Richard Henderson
#define INSN_IM11(x)     low_sign_ext(x, 11)
260 fd76e73a Richard Henderson
#define INSN_IM14(x)     low_sign_ext(x, 14)
261 fd76e73a Richard Henderson
#define INSN_IM5(x)      (low_sign_ext(x, 5) << 16)
262 fd76e73a Richard Henderson
263 fd76e73a Richard Henderson
#define COND_NEVER   0
264 fd76e73a Richard Henderson
#define COND_EQ      1
265 fd76e73a Richard Henderson
#define COND_LT      2
266 fd76e73a Richard Henderson
#define COND_LE      3
267 fd76e73a Richard Henderson
#define COND_LTU     4
268 fd76e73a Richard Henderson
#define COND_LEU     5
269 fd76e73a Richard Henderson
#define COND_SV      6
270 fd76e73a Richard Henderson
#define COND_OD      7
271 fd76e73a Richard Henderson
#define COND_FALSE   8
272 fd76e73a Richard Henderson
273 fd76e73a Richard Henderson
#define INSN_ADD        (INSN_OP(0x02) | INSN_EXT6(0x18))
274 fd76e73a Richard Henderson
#define INSN_ADDC        (INSN_OP(0x02) | INSN_EXT6(0x1c))
275 fd76e73a Richard Henderson
#define INSN_ADDI        (INSN_OP(0x2d))
276 fd76e73a Richard Henderson
#define INSN_ADDIL        (INSN_OP(0x0a))
277 fd76e73a Richard Henderson
#define INSN_ADDL        (INSN_OP(0x02) | INSN_EXT6(0x28))
278 fd76e73a Richard Henderson
#define INSN_AND        (INSN_OP(0x02) | INSN_EXT6(0x08))
279 fd76e73a Richard Henderson
#define INSN_ANDCM        (INSN_OP(0x02) | INSN_EXT6(0x00))
280 fd76e73a Richard Henderson
#define INSN_COMCLR        (INSN_OP(0x02) | INSN_EXT6(0x22))
281 fd76e73a Richard Henderson
#define INSN_COMICLR        (INSN_OP(0x24))
282 fd76e73a Richard Henderson
#define INSN_DEP        (INSN_OP(0x35) | INSN_EXT3SH(3))
283 fd76e73a Richard Henderson
#define INSN_DEPI        (INSN_OP(0x35) | INSN_EXT3SH(7))
284 fd76e73a Richard Henderson
#define INSN_EXTRS        (INSN_OP(0x34) | INSN_EXT3SH(7))
285 fd76e73a Richard Henderson
#define INSN_EXTRU        (INSN_OP(0x34) | INSN_EXT3SH(6))
286 fd76e73a Richard Henderson
#define INSN_LDIL        (INSN_OP(0x08))
287 fd76e73a Richard Henderson
#define INSN_LDO        (INSN_OP(0x0d))
288 fd76e73a Richard Henderson
#define INSN_MTCTL        (INSN_OP(0x00) | INSN_EXT8B(0xc2))
289 fd76e73a Richard Henderson
#define INSN_OR                (INSN_OP(0x02) | INSN_EXT6(0x09))
290 fd76e73a Richard Henderson
#define INSN_SHD        (INSN_OP(0x34) | INSN_EXT3SH(2))
291 fd76e73a Richard Henderson
#define INSN_SUB        (INSN_OP(0x02) | INSN_EXT6(0x10))
292 fd76e73a Richard Henderson
#define INSN_SUBB        (INSN_OP(0x02) | INSN_EXT6(0x14))
293 fd76e73a Richard Henderson
#define INSN_SUBI        (INSN_OP(0x25))
294 fd76e73a Richard Henderson
#define INSN_VEXTRS        (INSN_OP(0x34) | INSN_EXT3SH(5))
295 fd76e73a Richard Henderson
#define INSN_VEXTRU        (INSN_OP(0x34) | INSN_EXT3SH(4))
296 fd76e73a Richard Henderson
#define INSN_VSHD        (INSN_OP(0x34) | INSN_EXT3SH(0))
297 fd76e73a Richard Henderson
#define INSN_XOR        (INSN_OP(0x02) | INSN_EXT6(0x0a))
298 fd76e73a Richard Henderson
#define INSN_ZDEP        (INSN_OP(0x35) | INSN_EXT3SH(2))
299 fd76e73a Richard Henderson
#define INSN_ZVDEP        (INSN_OP(0x35) | INSN_EXT3SH(0))
300 fd76e73a Richard Henderson
301 fd76e73a Richard Henderson
#define INSN_BL         (INSN_OP(0x3a) | INSN_EXT3BR(0))
302 fd76e73a Richard Henderson
#define INSN_BL_N       (INSN_OP(0x3a) | INSN_EXT3BR(0) | 2)
303 fd76e73a Richard Henderson
#define INSN_BLR        (INSN_OP(0x3a) | INSN_EXT3BR(2))
304 fd76e73a Richard Henderson
#define INSN_BV         (INSN_OP(0x3a) | INSN_EXT3BR(6))
305 fd76e73a Richard Henderson
#define INSN_BV_N       (INSN_OP(0x3a) | INSN_EXT3BR(6) | 2)
306 fd76e73a Richard Henderson
#define INSN_BLE_SR4    (INSN_OP(0x39) | (1 << 13))
307 fd76e73a Richard Henderson
308 fd76e73a Richard Henderson
#define INSN_LDB        (INSN_OP(0x10))
309 fd76e73a Richard Henderson
#define INSN_LDH        (INSN_OP(0x11))
310 fd76e73a Richard Henderson
#define INSN_LDW        (INSN_OP(0x12))
311 fd76e73a Richard Henderson
#define INSN_LDWM       (INSN_OP(0x13))
312 fd76e73a Richard Henderson
#define INSN_FLDDS      (INSN_OP(0x0b) | INSN_EXT4(0) | (1 << 12))
313 fd76e73a Richard Henderson
314 fd76e73a Richard Henderson
#define INSN_LDBX        (INSN_OP(0x03) | INSN_EXT4(0))
315 fd76e73a Richard Henderson
#define INSN_LDHX        (INSN_OP(0x03) | INSN_EXT4(1))
316 fd76e73a Richard Henderson
#define INSN_LDWX       (INSN_OP(0x03) | INSN_EXT4(2))
317 fd76e73a Richard Henderson
318 fd76e73a Richard Henderson
#define INSN_STB        (INSN_OP(0x18))
319 fd76e73a Richard Henderson
#define INSN_STH        (INSN_OP(0x19))
320 fd76e73a Richard Henderson
#define INSN_STW        (INSN_OP(0x1a))
321 fd76e73a Richard Henderson
#define INSN_STWM       (INSN_OP(0x1b))
322 fd76e73a Richard Henderson
#define INSN_FSTDS      (INSN_OP(0x0b) | INSN_EXT4(8) | (1 << 12))
323 fd76e73a Richard Henderson
324 fd76e73a Richard Henderson
#define INSN_COMBT      (INSN_OP(0x20))
325 fd76e73a Richard Henderson
#define INSN_COMBF      (INSN_OP(0x22))
326 fd76e73a Richard Henderson
#define INSN_COMIBT     (INSN_OP(0x21))
327 fd76e73a Richard Henderson
#define INSN_COMIBF     (INSN_OP(0x23))
328 fd76e73a Richard Henderson
329 fd76e73a Richard Henderson
/* supplied by libgcc */
330 fd76e73a Richard Henderson
extern void *__canonicalize_funcptr_for_compare(void *);
331 fd76e73a Richard Henderson
332 fd76e73a Richard Henderson
static void tcg_out_mov(TCGContext *s, int ret, int arg)
333 fd76e73a Richard Henderson
{
334 fd76e73a Richard Henderson
    /* PA1.1 defines COPY as OR r,0,t; PA2.0 defines COPY as LDO 0(r),t
335 fd76e73a Richard Henderson
       but hppa-dis.c is unaware of this definition */
336 fd76e73a Richard Henderson
    if (ret != arg) {
337 fd76e73a Richard Henderson
        tcg_out32(s, INSN_OR | INSN_T(ret) | INSN_R1(arg)
338 fd76e73a Richard Henderson
                  | INSN_R2(TCG_REG_R0));
339 fd76e73a Richard Henderson
    }
340 fd76e73a Richard Henderson
}
341 f54b3f92 aurel32
342 fd76e73a Richard Henderson
static void tcg_out_movi(TCGContext *s, TCGType type,
343 fd76e73a Richard Henderson
                         int ret, tcg_target_long arg)
344 fd76e73a Richard Henderson
{
345 fd76e73a Richard Henderson
    if (check_fit_tl(arg, 14)) {
346 fd76e73a Richard Henderson
        tcg_out32(s, INSN_LDO | INSN_R1(ret)
347 fd76e73a Richard Henderson
                  | INSN_R2(TCG_REG_R0) | INSN_IM14(arg));
348 fd76e73a Richard Henderson
    } else {
349 fd76e73a Richard Henderson
        uint32_t hi, lo;
350 fd76e73a Richard Henderson
        hi = arg >> 11;
351 fd76e73a Richard Henderson
        lo = arg & 0x7ff;
352 fd76e73a Richard Henderson
353 fd76e73a Richard Henderson
        tcg_out32(s, INSN_LDIL | INSN_R2(ret) | reassemble_21(hi));
354 fd76e73a Richard Henderson
        if (lo) {
355 fd76e73a Richard Henderson
            tcg_out32(s, INSN_LDO | INSN_R1(ret)
356 fd76e73a Richard Henderson
                      | INSN_R2(ret) | INSN_IM14(lo));
357 fd76e73a Richard Henderson
        }
358 fd76e73a Richard Henderson
    }
359 fd76e73a Richard Henderson
}
360 f54b3f92 aurel32
361 fd76e73a Richard Henderson
static void tcg_out_ldst(TCGContext *s, int ret, int addr,
362 fd76e73a Richard Henderson
                         tcg_target_long offset, int op)
363 fd76e73a Richard Henderson
{
364 fd76e73a Richard Henderson
    if (!check_fit_tl(offset, 14)) {
365 fd76e73a Richard Henderson
        uint32_t hi, lo, op;
366 f54b3f92 aurel32
367 fd76e73a Richard Henderson
        hi = offset >> 11;
368 fd76e73a Richard Henderson
        lo = offset & 0x7ff;
369 f54b3f92 aurel32
370 fd76e73a Richard Henderson
        if (addr == TCG_REG_R0) {
371 fd76e73a Richard Henderson
            op = INSN_LDIL | INSN_R2(TCG_REG_R1);
372 fd76e73a Richard Henderson
        } else {
373 fd76e73a Richard Henderson
            op = INSN_ADDIL | INSN_R2(addr);
374 fd76e73a Richard Henderson
        }
375 fd76e73a Richard Henderson
        tcg_out32(s, op | reassemble_21(hi));
376 f54b3f92 aurel32
377 fd76e73a Richard Henderson
        addr = TCG_REG_R1;
378 fd76e73a Richard Henderson
        offset = lo;
379 fd76e73a Richard Henderson
    }
380 f54b3f92 aurel32
381 fd76e73a Richard Henderson
    if (ret != addr || offset != 0 || op != INSN_LDO) {
382 fd76e73a Richard Henderson
        tcg_out32(s, op | INSN_R1(ret) | INSN_R2(addr) | INSN_IM14(offset));
383 fd76e73a Richard Henderson
    }
384 fd76e73a Richard Henderson
}
385 f54b3f92 aurel32
386 fd76e73a Richard Henderson
/* This function is required by tcg.c.  */
387 fd76e73a Richard Henderson
static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
388 fd76e73a Richard Henderson
                              int arg1, tcg_target_long arg2)
389 fd76e73a Richard Henderson
{
390 fd76e73a Richard Henderson
    tcg_out_ldst(s, ret, arg1, arg2, INSN_LDW);
391 fd76e73a Richard Henderson
}
392 fd76e73a Richard Henderson
393 fd76e73a Richard Henderson
/* This function is required by tcg.c.  */
394 fd76e73a Richard Henderson
static inline void tcg_out_st(TCGContext *s, TCGType type, int ret,
395 fd76e73a Richard Henderson
                              int arg1, tcg_target_long arg2)
396 fd76e73a Richard Henderson
{
397 fd76e73a Richard Henderson
    tcg_out_ldst(s, ret, arg1, arg2, INSN_STW);
398 fd76e73a Richard Henderson
}
399 fd76e73a Richard Henderson
400 fd76e73a Richard Henderson
static void tcg_out_ldst_index(TCGContext *s, int data,
401 fd76e73a Richard Henderson
                               int base, int index, int op)
402 fd76e73a Richard Henderson
{
403 fd76e73a Richard Henderson
    tcg_out32(s, op | INSN_T(data) | INSN_R1(index) | INSN_R2(base));
404 fd76e73a Richard Henderson
}
405 fd76e73a Richard Henderson
406 fd76e73a Richard Henderson
static inline void tcg_out_addi2(TCGContext *s, int ret, int arg1,
407 fd76e73a Richard Henderson
                                 tcg_target_long val)
408 fd76e73a Richard Henderson
{
409 fd76e73a Richard Henderson
    tcg_out_ldst(s, ret, arg1, val, INSN_LDO);
410 fd76e73a Richard Henderson
}
411 f54b3f92 aurel32
412 fd76e73a Richard Henderson
/* This function is required by tcg.c.  */
413 fd76e73a Richard Henderson
static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
414 fd76e73a Richard Henderson
{
415 fd76e73a Richard Henderson
    tcg_out_addi2(s, reg, reg, val);
416 fd76e73a Richard Henderson
}
417 f54b3f92 aurel32
418 fd76e73a Richard Henderson
static inline void tcg_out_arith(TCGContext *s, int t, int r1, int r2, int op)
419 fd76e73a Richard Henderson
{
420 fd76e73a Richard Henderson
    tcg_out32(s, op | INSN_T(t) | INSN_R1(r1) | INSN_R2(r2));
421 fd76e73a Richard Henderson
}
422 f54b3f92 aurel32
423 fd76e73a Richard Henderson
static inline void tcg_out_arithi(TCGContext *s, int t, int r1,
424 fd76e73a Richard Henderson
                                  tcg_target_long val, int op)
425 f54b3f92 aurel32
{
426 fd76e73a Richard Henderson
    assert(check_fit_tl(val, 11));
427 fd76e73a Richard Henderson
    tcg_out32(s, op | INSN_R1(t) | INSN_R2(r1) | INSN_IM11(val));
428 f54b3f92 aurel32
}
429 f54b3f92 aurel32
430 fd76e73a Richard Henderson
static inline void tcg_out_nop(TCGContext *s)
431 f54b3f92 aurel32
{
432 fd76e73a Richard Henderson
    tcg_out_arith(s, TCG_REG_R0, TCG_REG_R0, TCG_REG_R0, INSN_OR);
433 fd76e73a Richard Henderson
}
434 f54b3f92 aurel32
435 fd76e73a Richard Henderson
static inline void tcg_out_mtctl_sar(TCGContext *s, int arg)
436 fd76e73a Richard Henderson
{
437 fd76e73a Richard Henderson
    tcg_out32(s, INSN_MTCTL | INSN_R2(11) | INSN_R1(arg));
438 fd76e73a Richard Henderson
}
439 fd76e73a Richard Henderson
440 fd76e73a Richard Henderson
/* Extract LEN bits at position OFS from ARG and place in RET.
441 fd76e73a Richard Henderson
   Note that here the bit ordering is reversed from the PA-RISC
442 fd76e73a Richard Henderson
   standard, such that the right-most bit is 0.  */
443 fd76e73a Richard Henderson
static inline void tcg_out_extr(TCGContext *s, int ret, int arg,
444 fd76e73a Richard Henderson
                                unsigned ofs, unsigned len, int sign)
445 fd76e73a Richard Henderson
{
446 fd76e73a Richard Henderson
    assert(ofs < 32 && len <= 32 - ofs);
447 fd76e73a Richard Henderson
    tcg_out32(s, (sign ? INSN_EXTRS : INSN_EXTRU)
448 fd76e73a Richard Henderson
              | INSN_R1(ret) | INSN_R2(arg)
449 fd76e73a Richard Henderson
              | INSN_SHDEP_P(31 - ofs) | INSN_DEP_LEN(len));
450 f54b3f92 aurel32
}
451 f54b3f92 aurel32
452 fd76e73a Richard Henderson
/* Likewise with OFS interpreted little-endian.  */
453 fd76e73a Richard Henderson
static inline void tcg_out_dep(TCGContext *s, int ret, int arg,
454 fd76e73a Richard Henderson
                               unsigned ofs, unsigned len)
455 f54b3f92 aurel32
{
456 fd76e73a Richard Henderson
    assert(ofs < 32 && len <= 32 - ofs);
457 fd76e73a Richard Henderson
    tcg_out32(s, INSN_DEP | INSN_R2(ret) | INSN_R1(arg)
458 fd76e73a Richard Henderson
              | INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len));
459 fd76e73a Richard Henderson
}
460 fd76e73a Richard Henderson
461 fd76e73a Richard Henderson
static inline void tcg_out_shd(TCGContext *s, int ret, int hi, int lo,
462 fd76e73a Richard Henderson
                               unsigned count)
463 fd76e73a Richard Henderson
{
464 fd76e73a Richard Henderson
    assert(count < 32);
465 fd76e73a Richard Henderson
    tcg_out32(s, INSN_SHD | INSN_R1(hi) | INSN_R2(lo) | INSN_T(ret)
466 fd76e73a Richard Henderson
              | INSN_SHDEP_CP(count));
467 fd76e73a Richard Henderson
}
468 fd76e73a Richard Henderson
469 fd76e73a Richard Henderson
static void tcg_out_vshd(TCGContext *s, int ret, int hi, int lo, int creg)
470 fd76e73a Richard Henderson
{
471 fd76e73a Richard Henderson
    tcg_out_mtctl_sar(s, creg);
472 fd76e73a Richard Henderson
    tcg_out32(s, INSN_VSHD | INSN_T(ret) | INSN_R1(hi) | INSN_R2(lo));
473 fd76e73a Richard Henderson
}
474 fd76e73a Richard Henderson
475 fd76e73a Richard Henderson
static void tcg_out_ori(TCGContext *s, int ret, int arg, tcg_target_ulong m)
476 fd76e73a Richard Henderson
{
477 fd76e73a Richard Henderson
    if (m == 0) {
478 fd76e73a Richard Henderson
        tcg_out_mov(s, ret, arg);
479 fd76e73a Richard Henderson
    } else if (m == -1) {
480 fd76e73a Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, ret, -1);
481 fd76e73a Richard Henderson
    } else if (or_mask_p(m)) {
482 fd76e73a Richard Henderson
        int bs0, bs1;
483 fd76e73a Richard Henderson
484 fd76e73a Richard Henderson
        for (bs0 = 0; bs0 < 32; bs0++) {
485 fd76e73a Richard Henderson
            if ((m & (1u << bs0)) != 0) {
486 fd76e73a Richard Henderson
                break;
487 fd76e73a Richard Henderson
            }
488 fd76e73a Richard Henderson
        }
489 fd76e73a Richard Henderson
        for (bs1 = bs0; bs1 < 32; bs1++) {
490 fd76e73a Richard Henderson
            if ((m & (1u << bs1)) == 0) {
491 fd76e73a Richard Henderson
                break;
492 fd76e73a Richard Henderson
            }
493 fd76e73a Richard Henderson
        }
494 fd76e73a Richard Henderson
        assert(bs1 == 32 || (1ul << bs1) > m);
495 fd76e73a Richard Henderson
496 fd76e73a Richard Henderson
        tcg_out_mov(s, ret, arg);
497 fd76e73a Richard Henderson
        tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1)
498 fd76e73a Richard Henderson
                  | INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0));
499 fd76e73a Richard Henderson
    } else {
500 fd76e73a Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R1, m);
501 fd76e73a Richard Henderson
        tcg_out_arith(s, ret, arg, TCG_REG_R1, INSN_OR);
502 fd76e73a Richard Henderson
    }
503 fd76e73a Richard Henderson
}
504 fd76e73a Richard Henderson
505 fd76e73a Richard Henderson
static void tcg_out_andi(TCGContext *s, int ret, int arg, tcg_target_ulong m)
506 fd76e73a Richard Henderson
{
507 fd76e73a Richard Henderson
    if (m == 0) {
508 fd76e73a Richard Henderson
        tcg_out_mov(s, ret, TCG_REG_R0);
509 fd76e73a Richard Henderson
    } else if (m == -1) {
510 fd76e73a Richard Henderson
        tcg_out_mov(s, ret, arg);
511 fd76e73a Richard Henderson
    } else if (and_mask_p(m)) {
512 fd76e73a Richard Henderson
        int ls0, ls1, ms0;
513 fd76e73a Richard Henderson
514 fd76e73a Richard Henderson
        for (ls0 = 0; ls0 < 32; ls0++) {
515 fd76e73a Richard Henderson
            if ((m & (1u << ls0)) == 0) {
516 fd76e73a Richard Henderson
                break;
517 fd76e73a Richard Henderson
            }
518 fd76e73a Richard Henderson
        }
519 fd76e73a Richard Henderson
        for (ls1 = ls0; ls1 < 32; ls1++) {
520 fd76e73a Richard Henderson
            if ((m & (1u << ls1)) != 0) {
521 fd76e73a Richard Henderson
                break;
522 fd76e73a Richard Henderson
            }
523 fd76e73a Richard Henderson
        }
524 fd76e73a Richard Henderson
        for (ms0 = ls1; ms0 < 32; ms0++) {
525 fd76e73a Richard Henderson
            if ((m & (1u << ms0)) == 0) {
526 fd76e73a Richard Henderson
                break;
527 fd76e73a Richard Henderson
            }
528 fd76e73a Richard Henderson
        }
529 fd76e73a Richard Henderson
        assert (ms0 == 32);
530 fd76e73a Richard Henderson
531 fd76e73a Richard Henderson
        if (ls1 == 32) {
532 fd76e73a Richard Henderson
            tcg_out_extr(s, ret, arg, 0, ls0, 0);
533 fd76e73a Richard Henderson
        } else {
534 fd76e73a Richard Henderson
            tcg_out_mov(s, ret, arg);
535 fd76e73a Richard Henderson
            tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0)
536 fd76e73a Richard Henderson
                      | INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0));
537 fd76e73a Richard Henderson
        }
538 f54b3f92 aurel32
    } else {
539 fd76e73a Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R1, m);
540 fd76e73a Richard Henderson
        tcg_out_arith(s, ret, arg, TCG_REG_R1, INSN_AND);
541 f54b3f92 aurel32
    }
542 f54b3f92 aurel32
}
543 f54b3f92 aurel32
544 fd76e73a Richard Henderson
static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
545 f54b3f92 aurel32
{
546 fd76e73a Richard Henderson
    tcg_out_extr(s, ret, arg, 0, 8, 1);
547 f54b3f92 aurel32
}
548 f54b3f92 aurel32
549 fd76e73a Richard Henderson
static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
550 f54b3f92 aurel32
{
551 fd76e73a Richard Henderson
    tcg_out_extr(s, ret, arg, 0, 16, 1);
552 f54b3f92 aurel32
}
553 f54b3f92 aurel32
554 fd76e73a Richard Henderson
static void tcg_out_shli(TCGContext *s, int ret, int arg, int count)
555 f54b3f92 aurel32
{
556 fd76e73a Richard Henderson
    count &= 31;
557 fd76e73a Richard Henderson
    tcg_out32(s, INSN_ZDEP | INSN_R2(ret) | INSN_R1(arg)
558 fd76e73a Richard Henderson
              | INSN_SHDEP_CP(31 - count) | INSN_DEP_LEN(32 - count));
559 f54b3f92 aurel32
}
560 f54b3f92 aurel32
561 fd76e73a Richard Henderson
static void tcg_out_shl(TCGContext *s, int ret, int arg, int creg)
562 f54b3f92 aurel32
{
563 fd76e73a Richard Henderson
    tcg_out_arithi(s, TCG_REG_R20, creg, 31, INSN_SUBI);
564 fd76e73a Richard Henderson
    tcg_out_mtctl_sar(s, TCG_REG_R20);
565 fd76e73a Richard Henderson
    tcg_out32(s, INSN_ZVDEP | INSN_R2(ret) | INSN_R1(arg) | INSN_DEP_LEN(32));
566 f54b3f92 aurel32
}
567 f54b3f92 aurel32
568 fd76e73a Richard Henderson
static void tcg_out_shri(TCGContext *s, int ret, int arg, int count)
569 f54b3f92 aurel32
{
570 fd76e73a Richard Henderson
    count &= 31;
571 fd76e73a Richard Henderson
    tcg_out_extr(s, ret, arg, count, 32 - count, 0);
572 f54b3f92 aurel32
}
573 f54b3f92 aurel32
574 fd76e73a Richard Henderson
static void tcg_out_shr(TCGContext *s, int ret, int arg, int creg)
575 f54b3f92 aurel32
{
576 fd76e73a Richard Henderson
    tcg_out_vshd(s, ret, TCG_REG_R0, arg, creg);
577 f54b3f92 aurel32
}
578 f54b3f92 aurel32
579 fd76e73a Richard Henderson
static void tcg_out_sari(TCGContext *s, int ret, int arg, int count)
580 f54b3f92 aurel32
{
581 fd76e73a Richard Henderson
    count &= 31;
582 fd76e73a Richard Henderson
    tcg_out_extr(s, ret, arg, count, 32 - count, 1);
583 f54b3f92 aurel32
}
584 f54b3f92 aurel32
585 fd76e73a Richard Henderson
static void tcg_out_sar(TCGContext *s, int ret, int arg, int creg)
586 f54b3f92 aurel32
{
587 fd76e73a Richard Henderson
    tcg_out_arithi(s, TCG_REG_R20, creg, 31, INSN_SUBI);
588 fd76e73a Richard Henderson
    tcg_out_mtctl_sar(s, TCG_REG_R20);
589 fd76e73a Richard Henderson
    tcg_out32(s, INSN_VEXTRS | INSN_R1(ret) | INSN_R2(arg) | INSN_DEP_LEN(32));
590 f54b3f92 aurel32
}
591 f54b3f92 aurel32
592 fd76e73a Richard Henderson
static void tcg_out_rotli(TCGContext *s, int ret, int arg, int count)
593 f54b3f92 aurel32
{
594 fd76e73a Richard Henderson
    count &= 31;
595 fd76e73a Richard Henderson
    tcg_out_shd(s, ret, arg, arg, 32 - count);
596 f54b3f92 aurel32
}
597 f54b3f92 aurel32
598 fd76e73a Richard Henderson
static void tcg_out_rotl(TCGContext *s, int ret, int arg, int creg)
599 fd76e73a Richard Henderson
{
600 fd76e73a Richard Henderson
    tcg_out_arithi(s, TCG_REG_R20, creg, 32, INSN_SUBI);
601 fd76e73a Richard Henderson
    tcg_out_vshd(s, ret, arg, arg, TCG_REG_R20);
602 f54b3f92 aurel32
}
603 f54b3f92 aurel32
604 fd76e73a Richard Henderson
static void tcg_out_rotri(TCGContext *s, int ret, int arg, int count)
605 fd76e73a Richard Henderson
{
606 fd76e73a Richard Henderson
    count &= 31;
607 fd76e73a Richard Henderson
    tcg_out_shd(s, ret, arg, arg, count);
608 f54b3f92 aurel32
}
609 f54b3f92 aurel32
610 fd76e73a Richard Henderson
static void tcg_out_rotr(TCGContext *s, int ret, int arg, int creg)
611 fd76e73a Richard Henderson
{
612 fd76e73a Richard Henderson
    tcg_out_vshd(s, ret, arg, arg, creg);
613 f54b3f92 aurel32
}
614 f54b3f92 aurel32
615 fd76e73a Richard Henderson
static void tcg_out_bswap16(TCGContext *s, int ret, int arg, int sign)
616 fd76e73a Richard Henderson
{
617 fd76e73a Richard Henderson
    if (ret != arg) {
618 fd76e73a Richard Henderson
        tcg_out_mov(s, ret, arg);             /* arg =  xxAB */
619 fd76e73a Richard Henderson
    }
620 fd76e73a Richard Henderson
    tcg_out_dep(s, ret, ret, 16, 8);          /* ret =  xBAB */
621 fd76e73a Richard Henderson
    tcg_out_extr(s, ret, ret, 8, 16, sign);   /* ret =  ..BA */
622 f54b3f92 aurel32
}
623 f54b3f92 aurel32
624 fd76e73a Richard Henderson
static void tcg_out_bswap32(TCGContext *s, int ret, int arg, int temp)
625 f54b3f92 aurel32
{
626 fd76e73a Richard Henderson
                                          /* arg =  ABCD */
627 fd76e73a Richard Henderson
    tcg_out_rotri(s, temp, arg, 16);      /* temp = CDAB */
628 fd76e73a Richard Henderson
    tcg_out_dep(s, temp, temp, 16, 8);    /* temp = CBAB */
629 fd76e73a Richard Henderson
    tcg_out_shd(s, ret, arg, temp, 8);    /* ret =  DCBA */
630 f54b3f92 aurel32
}
631 f54b3f92 aurel32
632 fd76e73a Richard Henderson
static void tcg_out_call(TCGContext *s, void *func)
633 fd76e73a Richard Henderson
{
634 fd76e73a Richard Henderson
    tcg_target_long val, hi, lo, disp;
635 fd76e73a Richard Henderson
636 fd76e73a Richard Henderson
    val = (uint32_t)__canonicalize_funcptr_for_compare(func);
637 fd76e73a Richard Henderson
    disp = (val - ((tcg_target_long)s->code_ptr + 8)) >> 2;
638 fd76e73a Richard Henderson
639 fd76e73a Richard Henderson
    if (check_fit_tl(disp, 17)) {
640 fd76e73a Richard Henderson
        tcg_out32(s, INSN_BL_N | INSN_R2(TCG_REG_RP) | reassemble_17(disp));
641 fd76e73a Richard Henderson
    } else {
642 fd76e73a Richard Henderson
        hi = val >> 11;
643 fd76e73a Richard Henderson
        lo = val & 0x7ff;
644 fd76e73a Richard Henderson
645 fd76e73a Richard Henderson
        tcg_out32(s, INSN_LDIL | INSN_R2(TCG_REG_R20) | reassemble_21(hi));
646 fd76e73a Richard Henderson
        tcg_out32(s, INSN_BLE_SR4 | INSN_R2(TCG_REG_R20)
647 fd76e73a Richard Henderson
                  | reassemble_17(lo >> 2));
648 fd76e73a Richard Henderson
        tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
649 fd76e73a Richard Henderson
    }
650 fd76e73a Richard Henderson
}
651 79383c9c blueswir1
652 fd76e73a Richard Henderson
static void tcg_out_xmpyu(TCGContext *s, int retl, int reth,
653 fd76e73a Richard Henderson
                          int arg1, int arg2)
654 fd76e73a Richard Henderson
{
655 fd76e73a Richard Henderson
    /* Store both words into the stack for copy to the FPU.  */
656 fd76e73a Richard Henderson
    tcg_out_ldst(s, arg1, TCG_REG_SP, STACK_TEMP_OFS, INSN_STW);
657 fd76e73a Richard Henderson
    tcg_out_ldst(s, arg2, TCG_REG_SP, STACK_TEMP_OFS + 4, INSN_STW);
658 fd76e73a Richard Henderson
659 fd76e73a Richard Henderson
    /* Load both words into the FPU at the same time.  We get away
660 fd76e73a Richard Henderson
       with this because we can address the left and right half of the
661 fd76e73a Richard Henderson
       FPU registers individually once loaded.  */
662 fd76e73a Richard Henderson
    /* fldds stack_temp(sp),fr22 */
663 fd76e73a Richard Henderson
    tcg_out32(s, INSN_FLDDS | INSN_R2(TCG_REG_SP)
664 fd76e73a Richard Henderson
              | INSN_IM5(STACK_TEMP_OFS) | INSN_T(22));
665 fd76e73a Richard Henderson
666 fd76e73a Richard Henderson
    /* xmpyu fr22r,fr22,fr22 */
667 fd76e73a Richard Henderson
    tcg_out32(s, 0x3ad64796);
668 fd76e73a Richard Henderson
669 fd76e73a Richard Henderson
    /* Store the 64-bit result back into the stack.  */
670 fd76e73a Richard Henderson
    /* fstds stack_temp(sp),fr22 */
671 fd76e73a Richard Henderson
    tcg_out32(s, INSN_FSTDS | INSN_R2(TCG_REG_SP)
672 fd76e73a Richard Henderson
              | INSN_IM5(STACK_TEMP_OFS) | INSN_T(22));
673 fd76e73a Richard Henderson
674 fd76e73a Richard Henderson
    /* Load the pieces of the result that the caller requested.  */
675 fd76e73a Richard Henderson
    if (reth) {
676 fd76e73a Richard Henderson
        tcg_out_ldst(s, reth, TCG_REG_SP, STACK_TEMP_OFS, INSN_LDW);
677 fd76e73a Richard Henderson
    }
678 fd76e73a Richard Henderson
    if (retl) {
679 fd76e73a Richard Henderson
        tcg_out_ldst(s, retl, TCG_REG_SP, STACK_TEMP_OFS + 4, INSN_LDW);
680 fd76e73a Richard Henderson
    }
681 fd76e73a Richard Henderson
}
682 fd76e73a Richard Henderson
683 91493631 Richard Henderson
static void tcg_out_add2(TCGContext *s, int destl, int desth,
684 91493631 Richard Henderson
                         int al, int ah, int bl, int bh, int blconst)
685 91493631 Richard Henderson
{
686 91493631 Richard Henderson
    int tmp = (destl == ah || destl == bh ? TCG_REG_R20 : destl);
687 91493631 Richard Henderson
688 91493631 Richard Henderson
    if (blconst) {
689 91493631 Richard Henderson
        tcg_out_arithi(s, tmp, al, bl, INSN_ADDI);
690 91493631 Richard Henderson
    } else {
691 91493631 Richard Henderson
        tcg_out_arith(s, tmp, al, bl, INSN_ADD);
692 91493631 Richard Henderson
    }
693 91493631 Richard Henderson
    tcg_out_arith(s, desth, ah, bh, INSN_ADDC);
694 91493631 Richard Henderson
695 91493631 Richard Henderson
    tcg_out_mov(s, destl, tmp);
696 91493631 Richard Henderson
}
697 91493631 Richard Henderson
698 91493631 Richard Henderson
static void tcg_out_sub2(TCGContext *s, int destl, int desth, int al, int ah,
699 91493631 Richard Henderson
                         int bl, int bh, int alconst, int blconst)
700 91493631 Richard Henderson
{
701 91493631 Richard Henderson
    int tmp = (destl == ah || destl == bh ? TCG_REG_R20 : destl);
702 91493631 Richard Henderson
703 91493631 Richard Henderson
    if (alconst) {
704 91493631 Richard Henderson
        if (blconst) {
705 91493631 Richard Henderson
            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R20, bl);
706 91493631 Richard Henderson
            bl = TCG_REG_R20;
707 91493631 Richard Henderson
        }
708 91493631 Richard Henderson
        tcg_out_arithi(s, tmp, bl, al, INSN_SUBI);
709 91493631 Richard Henderson
    } else if (blconst) {
710 91493631 Richard Henderson
        tcg_out_arithi(s, tmp, al, -bl, INSN_ADDI);
711 91493631 Richard Henderson
    } else {
712 91493631 Richard Henderson
        tcg_out_arith(s, tmp, al, bl, INSN_SUB);
713 91493631 Richard Henderson
    }
714 91493631 Richard Henderson
    tcg_out_arith(s, desth, ah, bh, INSN_SUBB);
715 91493631 Richard Henderson
716 91493631 Richard Henderson
    tcg_out_mov(s, destl, tmp);
717 91493631 Richard Henderson
}
718 91493631 Richard Henderson
719 fd76e73a Richard Henderson
static void tcg_out_branch(TCGContext *s, int label_index, int nul)
720 fd76e73a Richard Henderson
{
721 fd76e73a Richard Henderson
    TCGLabel *l = &s->labels[label_index];
722 fd76e73a Richard Henderson
    uint32_t op = nul ? INSN_BL_N : INSN_BL;
723 fd76e73a Richard Henderson
724 fd76e73a Richard Henderson
    if (l->has_value) {
725 fd76e73a Richard Henderson
        tcg_target_long val = l->u.value;
726 fd76e73a Richard Henderson
727 fd76e73a Richard Henderson
        val -= (tcg_target_long)s->code_ptr + 8;
728 fd76e73a Richard Henderson
        val >>= 2;
729 fd76e73a Richard Henderson
        assert(check_fit_tl(val, 17));
730 fd76e73a Richard Henderson
731 fd76e73a Richard Henderson
        tcg_out32(s, op | reassemble_17(val));
732 fd76e73a Richard Henderson
    } else {
733 fd76e73a Richard Henderson
        tcg_out_reloc(s, s->code_ptr, R_PARISC_PCREL17F, label_index, 0);
734 fd76e73a Richard Henderson
        tcg_out32(s, op);
735 fd76e73a Richard Henderson
    }
736 fd76e73a Richard Henderson
}
737 fd76e73a Richard Henderson
738 fd76e73a Richard Henderson
static const uint8_t tcg_cond_to_cmp_cond[10] =
739 fd76e73a Richard Henderson
{
740 fd76e73a Richard Henderson
    [TCG_COND_EQ] = COND_EQ,
741 fd76e73a Richard Henderson
    [TCG_COND_NE] = COND_EQ | COND_FALSE,
742 fd76e73a Richard Henderson
    [TCG_COND_LT] = COND_LT,
743 fd76e73a Richard Henderson
    [TCG_COND_GE] = COND_LT | COND_FALSE,
744 fd76e73a Richard Henderson
    [TCG_COND_LE] = COND_LE,
745 fd76e73a Richard Henderson
    [TCG_COND_GT] = COND_LE | COND_FALSE,
746 fd76e73a Richard Henderson
    [TCG_COND_LTU] = COND_LTU,
747 fd76e73a Richard Henderson
    [TCG_COND_GEU] = COND_LTU | COND_FALSE,
748 fd76e73a Richard Henderson
    [TCG_COND_LEU] = COND_LEU,
749 fd76e73a Richard Henderson
    [TCG_COND_GTU] = COND_LEU | COND_FALSE,
750 fd76e73a Richard Henderson
};
751 fd76e73a Richard Henderson
752 fd76e73a Richard Henderson
static void tcg_out_brcond(TCGContext *s, int cond, TCGArg c1,
753 fd76e73a Richard Henderson
                           TCGArg c2, int c2const, int label_index)
754 fd76e73a Richard Henderson
{
755 fd76e73a Richard Henderson
    TCGLabel *l = &s->labels[label_index];
756 fd76e73a Richard Henderson
    int op, pacond;
757 fd76e73a Richard Henderson
758 fd76e73a Richard Henderson
    /* Note that COMIB operates as if the immediate is the first
759 fd76e73a Richard Henderson
       operand.  We model brcond with the immediate in the second
760 fd76e73a Richard Henderson
       to better match what targets are likely to give us.  For
761 fd76e73a Richard Henderson
       consistency, model COMB with reversed operands as well.  */
762 fd76e73a Richard Henderson
    pacond = tcg_cond_to_cmp_cond[tcg_swap_cond(cond)];
763 fd76e73a Richard Henderson
764 fd76e73a Richard Henderson
    if (c2const) {
765 fd76e73a Richard Henderson
        op = (pacond & COND_FALSE ? INSN_COMIBF : INSN_COMIBT);
766 fd76e73a Richard Henderson
        op |= INSN_IM5(c2);
767 fd76e73a Richard Henderson
    } else {
768 fd76e73a Richard Henderson
        op = (pacond & COND_FALSE ? INSN_COMBF : INSN_COMBT);
769 fd76e73a Richard Henderson
        op |= INSN_R1(c2);
770 fd76e73a Richard Henderson
    }
771 fd76e73a Richard Henderson
    op |= INSN_R2(c1);
772 fd76e73a Richard Henderson
    op |= INSN_COND(pacond & 7);
773 fd76e73a Richard Henderson
774 fd76e73a Richard Henderson
    if (l->has_value) {
775 fd76e73a Richard Henderson
        tcg_target_long val = l->u.value;
776 fd76e73a Richard Henderson
777 fd76e73a Richard Henderson
        val -= (tcg_target_long)s->code_ptr + 8;
778 fd76e73a Richard Henderson
        val >>= 2;
779 fd76e73a Richard Henderson
        assert(check_fit_tl(val, 12));
780 fd76e73a Richard Henderson
781 fd76e73a Richard Henderson
        /* ??? Assume that all branches to defined labels are backward.
782 fd76e73a Richard Henderson
           Which means that if the nul bit is set, the delay slot is
783 fd76e73a Richard Henderson
           executed if the branch is taken, and not executed in fallthru.  */
784 fd76e73a Richard Henderson
        tcg_out32(s, op | reassemble_12(val));
785 fd76e73a Richard Henderson
        tcg_out_nop(s);
786 fd76e73a Richard Henderson
    } else {
787 fd76e73a Richard Henderson
        tcg_out_reloc(s, s->code_ptr, R_PARISC_PCREL12F, label_index, 0);
788 fd76e73a Richard Henderson
        /* ??? Assume that all branches to undefined labels are forward.
789 fd76e73a Richard Henderson
           Which means that if the nul bit is set, the delay slot is
790 fd76e73a Richard Henderson
           not executed if the branch is taken, which is what we want.  */
791 fd76e73a Richard Henderson
        tcg_out32(s, op | 2);
792 fd76e73a Richard Henderson
    }
793 fd76e73a Richard Henderson
}
794 fd76e73a Richard Henderson
795 fd76e73a Richard Henderson
static void tcg_out_comclr(TCGContext *s, int cond, TCGArg ret,
796 fd76e73a Richard Henderson
                           TCGArg c1, TCGArg c2, int c2const)
797 fd76e73a Richard Henderson
{
798 fd76e73a Richard Henderson
    int op, pacond;
799 fd76e73a Richard Henderson
800 fd76e73a Richard Henderson
    /* Note that COMICLR operates as if the immediate is the first
801 fd76e73a Richard Henderson
       operand.  We model setcond with the immediate in the second
802 fd76e73a Richard Henderson
       to better match what targets are likely to give us.  For
803 fd76e73a Richard Henderson
       consistency, model COMCLR with reversed operands as well.  */
804 fd76e73a Richard Henderson
    pacond = tcg_cond_to_cmp_cond[tcg_swap_cond(cond)];
805 fd76e73a Richard Henderson
806 fd76e73a Richard Henderson
    if (c2const) {
807 fd76e73a Richard Henderson
        op = INSN_COMICLR | INSN_R2(c1) | INSN_R1(ret) | INSN_IM11(c2);
808 fd76e73a Richard Henderson
    } else {
809 fd76e73a Richard Henderson
        op = INSN_COMCLR | INSN_R2(c1) | INSN_R1(c2) | INSN_T(ret);
810 fd76e73a Richard Henderson
    }
811 fd76e73a Richard Henderson
    op |= INSN_COND(pacond & 7);
812 fd76e73a Richard Henderson
    op |= pacond & COND_FALSE ? 1 << 12 : 0;
813 fd76e73a Richard Henderson
814 fd76e73a Richard Henderson
    tcg_out32(s, op);
815 fd76e73a Richard Henderson
}
816 fd76e73a Richard Henderson
817 fd76e73a Richard Henderson
static void tcg_out_brcond2(TCGContext *s, int cond, TCGArg al, TCGArg ah,
818 fd76e73a Richard Henderson
                            TCGArg bl, int blconst, TCGArg bh, int bhconst,
819 fd76e73a Richard Henderson
                            int label_index)
820 fd76e73a Richard Henderson
{
821 fd76e73a Richard Henderson
    switch (cond) {
822 fd76e73a Richard Henderson
    case TCG_COND_EQ:
823 fd76e73a Richard Henderson
    case TCG_COND_NE:
824 fd76e73a Richard Henderson
        tcg_out_comclr(s, tcg_invert_cond(cond), TCG_REG_R0, al, bl, blconst);
825 fd76e73a Richard Henderson
        tcg_out_brcond(s, cond, ah, bh, bhconst, label_index);
826 fd76e73a Richard Henderson
        break;
827 fd76e73a Richard Henderson
828 fd76e73a Richard Henderson
    default:
829 fd76e73a Richard Henderson
        tcg_out_brcond(s, cond, ah, bh, bhconst, label_index);
830 fd76e73a Richard Henderson
        tcg_out_comclr(s, TCG_COND_NE, TCG_REG_R0, ah, bh, bhconst);
831 fd76e73a Richard Henderson
        tcg_out_brcond(s, tcg_unsigned_cond(cond),
832 fd76e73a Richard Henderson
                       al, bl, blconst, label_index);
833 fd76e73a Richard Henderson
        break;
834 fd76e73a Richard Henderson
    }
835 fd76e73a Richard Henderson
}
836 fd76e73a Richard Henderson
837 fd76e73a Richard Henderson
static void tcg_out_setcond(TCGContext *s, int cond, TCGArg ret,
838 fd76e73a Richard Henderson
                            TCGArg c1, TCGArg c2, int c2const)
839 fd76e73a Richard Henderson
{
840 fd76e73a Richard Henderson
    tcg_out_comclr(s, tcg_invert_cond(cond), ret, c1, c2, c2const);
841 fd76e73a Richard Henderson
    tcg_out_movi(s, TCG_TYPE_I32, ret, 1);
842 fd76e73a Richard Henderson
}
843 fd76e73a Richard Henderson
844 fd76e73a Richard Henderson
static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret,
845 fd76e73a Richard Henderson
                             TCGArg al, TCGArg ah, TCGArg bl, int blconst,
846 fd76e73a Richard Henderson
                             TCGArg bh, int bhconst)
847 fd76e73a Richard Henderson
{
848 fd76e73a Richard Henderson
    int scratch = TCG_REG_R20;
849 fd76e73a Richard Henderson
850 fd76e73a Richard Henderson
    if (ret != al && ret != ah
851 fd76e73a Richard Henderson
        && (blconst || ret != bl)
852 fd76e73a Richard Henderson
        && (bhconst || ret != bh)) {
853 fd76e73a Richard Henderson
        scratch = ret;
854 fd76e73a Richard Henderson
    }
855 fd76e73a Richard Henderson
856 fd76e73a Richard Henderson
    switch (cond) {
857 fd76e73a Richard Henderson
    case TCG_COND_EQ:
858 fd76e73a Richard Henderson
    case TCG_COND_NE:
859 fd76e73a Richard Henderson
        tcg_out_setcond(s, cond, scratch, al, bl, blconst);
860 fd76e73a Richard Henderson
        tcg_out_comclr(s, TCG_COND_EQ, TCG_REG_R0, ah, bh, bhconst);
861 fd76e73a Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, scratch, cond == TCG_COND_NE);
862 fd76e73a Richard Henderson
        break;
863 fd76e73a Richard Henderson
864 fd76e73a Richard Henderson
    default:
865 fd76e73a Richard Henderson
        tcg_out_setcond(s, tcg_unsigned_cond(cond), scratch, al, bl, blconst);
866 fd76e73a Richard Henderson
        tcg_out_comclr(s, TCG_COND_EQ, TCG_REG_R0, ah, bh, bhconst);
867 fd76e73a Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, scratch, 0);
868 fd76e73a Richard Henderson
        tcg_out_comclr(s, cond, TCG_REG_R0, ah, bh, bhconst);
869 fd76e73a Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, scratch, 1);
870 fd76e73a Richard Henderson
        break;
871 fd76e73a Richard Henderson
    }
872 fd76e73a Richard Henderson
873 fd76e73a Richard Henderson
    tcg_out_mov(s, ret, scratch);
874 fd76e73a Richard Henderson
}
875 fd76e73a Richard Henderson
876 fd76e73a Richard Henderson
#if defined(CONFIG_SOFTMMU)
877 79383c9c blueswir1
#include "../../softmmu_defs.h"
878 f54b3f92 aurel32
879 f54b3f92 aurel32
static void *qemu_ld_helpers[4] = {
880 f54b3f92 aurel32
    __ldb_mmu,
881 f54b3f92 aurel32
    __ldw_mmu,
882 f54b3f92 aurel32
    __ldl_mmu,
883 f54b3f92 aurel32
    __ldq_mmu,
884 f54b3f92 aurel32
};
885 f54b3f92 aurel32
886 f54b3f92 aurel32
static void *qemu_st_helpers[4] = {
887 f54b3f92 aurel32
    __stb_mmu,
888 f54b3f92 aurel32
    __stw_mmu,
889 f54b3f92 aurel32
    __stl_mmu,
890 f54b3f92 aurel32
    __stq_mmu,
891 f54b3f92 aurel32
};
892 fd76e73a Richard Henderson
893 fd76e73a Richard Henderson
/* Load and compare a TLB entry, and branch if TLB miss.  OFFSET is set to
894 fd76e73a Richard Henderson
   the offset of the first ADDR_READ or ADDR_WRITE member of the appropriate
895 fd76e73a Richard Henderson
   TLB for the memory index.  The return value is the offset from ENV
896 fd76e73a Richard Henderson
   contained in R1 afterward (to be used when loading ADDEND); if the
897 fd76e73a Richard Henderson
   return value is 0, R1 is not used.  */
898 fd76e73a Richard Henderson
899 fd76e73a Richard Henderson
static int tcg_out_tlb_read(TCGContext *s, int r0, int r1, int addrlo,
900 fd76e73a Richard Henderson
                            int addrhi, int s_bits, int lab_miss, int offset)
901 fd76e73a Richard Henderson
{
902 fd76e73a Richard Henderson
    int ret;
903 fd76e73a Richard Henderson
904 fd76e73a Richard Henderson
    /* Extracting the index into the TLB.  The "normal C operation" is
905 fd76e73a Richard Henderson
          r1 = addr_reg >> TARGET_PAGE_BITS;
906 fd76e73a Richard Henderson
          r1 &= CPU_TLB_SIZE - 1;
907 fd76e73a Richard Henderson
          r1 <<= CPU_TLB_ENTRY_BITS;
908 fd76e73a Richard Henderson
       What this does is extract CPU_TLB_BITS beginning at TARGET_PAGE_BITS
909 fd76e73a Richard Henderson
       and place them at CPU_TLB_ENTRY_BITS.  We can combine the first two
910 fd76e73a Richard Henderson
       operations with an EXTRU.  Unfortunately, the current value of
911 fd76e73a Richard Henderson
       CPU_TLB_ENTRY_BITS is > 3, so we can't merge that shift with the
912 fd76e73a Richard Henderson
       add that follows.  */
913 fd76e73a Richard Henderson
    tcg_out_extr(s, r1, addrlo, TARGET_PAGE_BITS, CPU_TLB_BITS, 0);
914 fd76e73a Richard Henderson
    tcg_out_andi(s, r0, addrlo, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
915 fd76e73a Richard Henderson
    tcg_out_shli(s, r1, r1, CPU_TLB_ENTRY_BITS);
916 fd76e73a Richard Henderson
    tcg_out_arith(s, r1, r1, TCG_AREG0, INSN_ADDL);
917 fd76e73a Richard Henderson
918 fd76e73a Richard Henderson
    /* Make sure that both the addr_{read,write} and addend can be
919 fd76e73a Richard Henderson
       read with a 14-bit offset from the same base register.  */
920 fd76e73a Richard Henderson
    if (check_fit_tl(offset + CPU_TLB_SIZE, 14)) {
921 fd76e73a Richard Henderson
        ret = 0;
922 fd76e73a Richard Henderson
    } else {
923 fd76e73a Richard Henderson
        ret = (offset + 0x400) & ~0x7ff;
924 fd76e73a Richard Henderson
        offset = ret - offset;
925 fd76e73a Richard Henderson
        tcg_out_addi2(s, TCG_REG_R1, r1, ret);
926 fd76e73a Richard Henderson
        r1 = TCG_REG_R1;
927 fd76e73a Richard Henderson
    }
928 fd76e73a Richard Henderson
929 fd76e73a Richard Henderson
    /* Load the entry from the computed slot.  */
930 fd76e73a Richard Henderson
    if (TARGET_LONG_BITS == 64) {
931 fd76e73a Richard Henderson
        tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R23, r1, offset);
932 fd76e73a Richard Henderson
        tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, r1, offset + 4);
933 fd76e73a Richard Henderson
    } else {
934 fd76e73a Richard Henderson
        tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, r1, offset);
935 fd76e73a Richard Henderson
    }
936 fd76e73a Richard Henderson
937 fd76e73a Richard Henderson
    /* If not equal, jump to lab_miss. */
938 fd76e73a Richard Henderson
    if (TARGET_LONG_BITS == 64) {
939 fd76e73a Richard Henderson
        tcg_out_brcond2(s, TCG_COND_NE, TCG_REG_R20, TCG_REG_R23,
940 fd76e73a Richard Henderson
                        r0, 0, addrhi, 0, lab_miss);
941 fd76e73a Richard Henderson
    } else {
942 fd76e73a Richard Henderson
        tcg_out_brcond(s, TCG_COND_NE, TCG_REG_R20, r0, 0, lab_miss);
943 fd76e73a Richard Henderson
    }
944 fd76e73a Richard Henderson
945 fd76e73a Richard Henderson
    return ret;
946 fd76e73a Richard Henderson
}
947 f54b3f92 aurel32
#endif
948 f54b3f92 aurel32
949 f54b3f92 aurel32
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
950 f54b3f92 aurel32
{
951 fd76e73a Richard Henderson
    int addr_reg, addr_reg2;
952 fd76e73a Richard Henderson
    int data_reg, data_reg2;
953 fd76e73a Richard Henderson
    int r0, r1, mem_index, s_bits, bswap;
954 fd76e73a Richard Henderson
    tcg_target_long offset;
955 f54b3f92 aurel32
#if defined(CONFIG_SOFTMMU)
956 fd76e73a Richard Henderson
    int lab1, lab2, argreg;
957 f54b3f92 aurel32
#endif
958 f54b3f92 aurel32
959 f54b3f92 aurel32
    data_reg = *args++;
960 fd76e73a Richard Henderson
    data_reg2 = (opc == 3 ? *args++ : TCG_REG_R0);
961 f54b3f92 aurel32
    addr_reg = *args++;
962 fd76e73a Richard Henderson
    addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : TCG_REG_R0);
963 f54b3f92 aurel32
    mem_index = *args;
964 f54b3f92 aurel32
    s_bits = opc & 3;
965 f54b3f92 aurel32
966 f54b3f92 aurel32
    r0 = TCG_REG_R26;
967 f54b3f92 aurel32
    r1 = TCG_REG_R25;
968 f54b3f92 aurel32
969 f54b3f92 aurel32
#if defined(CONFIG_SOFTMMU)
970 fd76e73a Richard Henderson
    lab1 = gen_new_label();
971 fd76e73a Richard Henderson
    lab2 = gen_new_label();
972 f54b3f92 aurel32
973 fd76e73a Richard Henderson
    offset = tcg_out_tlb_read(s, r0, r1, addr_reg, addr_reg2, s_bits, lab1,
974 fd76e73a Richard Henderson
                              offsetof(CPUState,
975 fd76e73a Richard Henderson
                                       tlb_table[mem_index][0].addr_read));
976 f54b3f92 aurel32
977 fd76e73a Richard Henderson
    /* TLB Hit.  */
978 fd76e73a Richard Henderson
    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : r1),
979 fd76e73a Richard Henderson
               offsetof(CPUState, tlb_table[mem_index][0].addend) - offset);
980 f54b3f92 aurel32
981 fd76e73a Richard Henderson
    tcg_out_arith(s, r0, addr_reg, TCG_REG_R20, INSN_ADDL);
982 fd76e73a Richard Henderson
    offset = TCG_REG_R0;
983 f54b3f92 aurel32
#else
984 f54b3f92 aurel32
    r0 = addr_reg;
985 fd76e73a Richard Henderson
    offset = GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_R0;
986 f54b3f92 aurel32
#endif
987 f54b3f92 aurel32
988 f54b3f92 aurel32
#ifdef TARGET_WORDS_BIGENDIAN
989 f54b3f92 aurel32
    bswap = 0;
990 f54b3f92 aurel32
#else
991 f54b3f92 aurel32
    bswap = 1;
992 f54b3f92 aurel32
#endif
993 f54b3f92 aurel32
    switch (opc) {
994 fd76e73a Richard Henderson
    case 0:
995 fd76e73a Richard Henderson
        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDBX);
996 fd76e73a Richard Henderson
        break;
997 fd76e73a Richard Henderson
    case 0 | 4:
998 fd76e73a Richard Henderson
        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDBX);
999 fd76e73a Richard Henderson
        tcg_out_ext8s(s, data_reg, data_reg);
1000 fd76e73a Richard Henderson
        break;
1001 fd76e73a Richard Henderson
    case 1:
1002 fd76e73a Richard Henderson
        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDHX);
1003 fd76e73a Richard Henderson
        if (bswap) {
1004 fd76e73a Richard Henderson
            tcg_out_bswap16(s, data_reg, data_reg, 0);
1005 fd76e73a Richard Henderson
        }
1006 fd76e73a Richard Henderson
        break;
1007 fd76e73a Richard Henderson
    case 1 | 4:
1008 fd76e73a Richard Henderson
        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDHX);
1009 fd76e73a Richard Henderson
        if (bswap) {
1010 fd76e73a Richard Henderson
            tcg_out_bswap16(s, data_reg, data_reg, 1);
1011 fd76e73a Richard Henderson
        } else {
1012 f54b3f92 aurel32
            tcg_out_ext16s(s, data_reg, data_reg);
1013 fd76e73a Richard Henderson
        }
1014 fd76e73a Richard Henderson
        break;
1015 fd76e73a Richard Henderson
    case 2:
1016 fd76e73a Richard Henderson
        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDWX);
1017 fd76e73a Richard Henderson
        if (bswap) {
1018 fd76e73a Richard Henderson
            tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
1019 fd76e73a Richard Henderson
        }
1020 fd76e73a Richard Henderson
        break;
1021 fd76e73a Richard Henderson
    case 3:
1022 fd76e73a Richard Henderson
        if (bswap) {
1023 fd76e73a Richard Henderson
            int t = data_reg2;
1024 fd76e73a Richard Henderson
            data_reg2 = data_reg;
1025 fd76e73a Richard Henderson
            data_reg = t;
1026 fd76e73a Richard Henderson
        }
1027 fd76e73a Richard Henderson
        if (offset == TCG_REG_R0) {
1028 fd76e73a Richard Henderson
            /* Make sure not to clobber the base register.  */
1029 fd76e73a Richard Henderson
            if (data_reg2 == r0) {
1030 fd76e73a Richard Henderson
                tcg_out_ldst(s, data_reg, r0, 4, INSN_LDW);
1031 fd76e73a Richard Henderson
                tcg_out_ldst(s, data_reg2, r0, 0, INSN_LDW);
1032 f54b3f92 aurel32
            } else {
1033 fd76e73a Richard Henderson
                tcg_out_ldst(s, data_reg2, r0, 0, INSN_LDW);
1034 fd76e73a Richard Henderson
                tcg_out_ldst(s, data_reg, r0, 4, INSN_LDW);
1035 f54b3f92 aurel32
            }
1036 fd76e73a Richard Henderson
        } else {
1037 fd76e73a Richard Henderson
            tcg_out_addi2(s, TCG_REG_R20, r0, 4);
1038 fd76e73a Richard Henderson
            tcg_out_ldst_index(s, data_reg2, r0, offset, INSN_LDWX);
1039 fd76e73a Richard Henderson
            tcg_out_ldst_index(s, data_reg, TCG_REG_R20, offset, INSN_LDWX);
1040 fd76e73a Richard Henderson
        }
1041 fd76e73a Richard Henderson
        if (bswap) {
1042 fd76e73a Richard Henderson
            tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
1043 fd76e73a Richard Henderson
            tcg_out_bswap32(s, data_reg2, data_reg2, TCG_REG_R20);
1044 fd76e73a Richard Henderson
        }
1045 fd76e73a Richard Henderson
        break;
1046 fd76e73a Richard Henderson
    default:
1047 fd76e73a Richard Henderson
        tcg_abort();
1048 f54b3f92 aurel32
    }
1049 f54b3f92 aurel32
1050 f54b3f92 aurel32
#if defined(CONFIG_SOFTMMU)
1051 fd76e73a Richard Henderson
    tcg_out_branch(s, lab2, 1);
1052 fd76e73a Richard Henderson
1053 fd76e73a Richard Henderson
    /* TLB Miss.  */
1054 fd76e73a Richard Henderson
    /* label1: */
1055 fd76e73a Richard Henderson
    tcg_out_label(s, lab1, (tcg_target_long)s->code_ptr);
1056 fd76e73a Richard Henderson
1057 fd76e73a Richard Henderson
    argreg = TCG_REG_R26;
1058 fd76e73a Richard Henderson
    tcg_out_mov(s, argreg--, addr_reg);
1059 fd76e73a Richard Henderson
    if (TARGET_LONG_BITS == 64) {
1060 fd76e73a Richard Henderson
        tcg_out_mov(s, argreg--, addr_reg2);
1061 fd76e73a Richard Henderson
    }
1062 fd76e73a Richard Henderson
    tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
1063 fd76e73a Richard Henderson
1064 fd76e73a Richard Henderson
    tcg_out_call(s, qemu_ld_helpers[s_bits]);
1065 fd76e73a Richard Henderson
1066 fd76e73a Richard Henderson
    switch (opc) {
1067 fd76e73a Richard Henderson
    case 0:
1068 fd76e73a Richard Henderson
        tcg_out_andi(s, data_reg, TCG_REG_RET0, 0xff);
1069 fd76e73a Richard Henderson
        break;
1070 fd76e73a Richard Henderson
    case 0 | 4:
1071 fd76e73a Richard Henderson
        tcg_out_ext8s(s, data_reg, TCG_REG_RET0);
1072 fd76e73a Richard Henderson
        break;
1073 fd76e73a Richard Henderson
    case 1:
1074 fd76e73a Richard Henderson
        tcg_out_andi(s, data_reg, TCG_REG_RET0, 0xffff);
1075 fd76e73a Richard Henderson
        break;
1076 fd76e73a Richard Henderson
    case 1 | 4:
1077 fd76e73a Richard Henderson
        tcg_out_ext16s(s, data_reg, TCG_REG_RET0);
1078 fd76e73a Richard Henderson
        break;
1079 fd76e73a Richard Henderson
    case 2:
1080 fd76e73a Richard Henderson
    case 2 | 4:
1081 fd76e73a Richard Henderson
        tcg_out_mov(s, data_reg, TCG_REG_RET0);
1082 fd76e73a Richard Henderson
        break;
1083 fd76e73a Richard Henderson
    case 3:
1084 fd76e73a Richard Henderson
        tcg_out_mov(s, data_reg, TCG_REG_RET0);
1085 fd76e73a Richard Henderson
        tcg_out_mov(s, data_reg2, TCG_REG_RET1);
1086 fd76e73a Richard Henderson
        break;
1087 fd76e73a Richard Henderson
    default:
1088 fd76e73a Richard Henderson
        tcg_abort();
1089 fd76e73a Richard Henderson
    }
1090 fd76e73a Richard Henderson
1091 f54b3f92 aurel32
    /* label2: */
1092 fd76e73a Richard Henderson
    tcg_out_label(s, lab2, (tcg_target_long)s->code_ptr);
1093 f54b3f92 aurel32
#endif
1094 f54b3f92 aurel32
}
1095 f54b3f92 aurel32
1096 f54b3f92 aurel32
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
1097 f54b3f92 aurel32
{
1098 fd76e73a Richard Henderson
    int addr_reg, addr_reg2;
1099 fd76e73a Richard Henderson
    int data_reg, data_reg2;
1100 fd76e73a Richard Henderson
    int r0, r1, mem_index, s_bits, bswap;
1101 f54b3f92 aurel32
#if defined(CONFIG_SOFTMMU)
1102 fd76e73a Richard Henderson
    tcg_target_long offset;
1103 fd76e73a Richard Henderson
    int lab1, lab2, argreg;
1104 f54b3f92 aurel32
#endif
1105 f54b3f92 aurel32
1106 f54b3f92 aurel32
    data_reg = *args++;
1107 fd76e73a Richard Henderson
    data_reg2 = (opc == 3 ? *args++ : 0);
1108 f54b3f92 aurel32
    addr_reg = *args++;
1109 fd76e73a Richard Henderson
    addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1110 f54b3f92 aurel32
    mem_index = *args;
1111 f54b3f92 aurel32
    s_bits = opc;
1112 f54b3f92 aurel32
1113 f54b3f92 aurel32
    r0 = TCG_REG_R26;
1114 f54b3f92 aurel32
    r1 = TCG_REG_R25;
1115 f54b3f92 aurel32
1116 f54b3f92 aurel32
#if defined(CONFIG_SOFTMMU)
1117 fd76e73a Richard Henderson
    lab1 = gen_new_label();
1118 fd76e73a Richard Henderson
    lab2 = gen_new_label();
1119 f54b3f92 aurel32
1120 fd76e73a Richard Henderson
    offset = tcg_out_tlb_read(s, r0, r1, addr_reg, addr_reg2, s_bits, lab1,
1121 fd76e73a Richard Henderson
                              offsetof(CPUState,
1122 fd76e73a Richard Henderson
                                       tlb_table[mem_index][0].addr_write));
1123 f54b3f92 aurel32
1124 fd76e73a Richard Henderson
    /* TLB Hit.  */
1125 fd76e73a Richard Henderson
    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : r1),
1126 fd76e73a Richard Henderson
               offsetof(CPUState, tlb_table[mem_index][0].addend) - offset);
1127 f54b3f92 aurel32
1128 fd76e73a Richard Henderson
    tcg_out_arith(s, r0, addr_reg, TCG_REG_R20, INSN_ADDL);
1129 f54b3f92 aurel32
#else
1130 fd76e73a Richard Henderson
    /* There are no indexed stores, so if GUEST_BASE is set
1131 fd76e73a Richard Henderson
       we must do the add explicitly.  Careful to avoid R20,
1132 fd76e73a Richard Henderson
       which is used for the bswaps to follow.  */
1133 fd76e73a Richard Henderson
    if (GUEST_BASE == 0) {
1134 fd76e73a Richard Henderson
        r0 = addr_reg;
1135 f54b3f92 aurel32
    } else {
1136 fd76e73a Richard Henderson
        tcg_out_arith(s, TCG_REG_R31, addr_reg, TCG_GUEST_BASE_REG, INSN_ADDL);
1137 fd76e73a Richard Henderson
        r0 = TCG_REG_R31;
1138 f54b3f92 aurel32
    }
1139 f54b3f92 aurel32
#endif
1140 f54b3f92 aurel32
1141 f54b3f92 aurel32
#ifdef TARGET_WORDS_BIGENDIAN
1142 f54b3f92 aurel32
    bswap = 0;
1143 f54b3f92 aurel32
#else
1144 f54b3f92 aurel32
    bswap = 1;
1145 f54b3f92 aurel32
#endif
1146 f54b3f92 aurel32
    switch (opc) {
1147 f54b3f92 aurel32
    case 0:
1148 fd76e73a Richard Henderson
        tcg_out_ldst(s, data_reg, r0, 0, INSN_STB);
1149 f54b3f92 aurel32
        break;
1150 f54b3f92 aurel32
    case 1:
1151 f54b3f92 aurel32
        if (bswap) {
1152 fd76e73a Richard Henderson
            tcg_out_bswap16(s, TCG_REG_R20, data_reg, 0);
1153 f54b3f92 aurel32
            data_reg = TCG_REG_R20;
1154 f54b3f92 aurel32
        }
1155 fd76e73a Richard Henderson
        tcg_out_ldst(s, data_reg, r0, 0, INSN_STH);
1156 f54b3f92 aurel32
        break;
1157 f54b3f92 aurel32
    case 2:
1158 f54b3f92 aurel32
        if (bswap) {
1159 f54b3f92 aurel32
            tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);
1160 f54b3f92 aurel32
            data_reg = TCG_REG_R20;
1161 f54b3f92 aurel32
        }
1162 fd76e73a Richard Henderson
        tcg_out_ldst(s, data_reg, r0, 0, INSN_STW);
1163 f54b3f92 aurel32
        break;
1164 f54b3f92 aurel32
    case 3:
1165 fd76e73a Richard Henderson
        if (bswap) {
1166 f54b3f92 aurel32
            tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);
1167 fd76e73a Richard Henderson
            tcg_out_bswap32(s, TCG_REG_R23, data_reg2, TCG_REG_R23);
1168 fd76e73a Richard Henderson
            data_reg2 = TCG_REG_R20;
1169 fd76e73a Richard Henderson
            data_reg = TCG_REG_R23;
1170 f54b3f92 aurel32
        }
1171 fd76e73a Richard Henderson
        tcg_out_ldst(s, data_reg2, r0, 0, INSN_STW);
1172 fd76e73a Richard Henderson
        tcg_out_ldst(s, data_reg, r0, 4, INSN_STW);
1173 f54b3f92 aurel32
        break;
1174 f54b3f92 aurel32
    default:
1175 f54b3f92 aurel32
        tcg_abort();
1176 f54b3f92 aurel32
    }
1177 f54b3f92 aurel32
1178 f54b3f92 aurel32
#if defined(CONFIG_SOFTMMU)
1179 fd76e73a Richard Henderson
    tcg_out_branch(s, lab2, 1);
1180 fd76e73a Richard Henderson
1181 fd76e73a Richard Henderson
    /* TLB Miss.  */
1182 fd76e73a Richard Henderson
    /* label1: */
1183 fd76e73a Richard Henderson
    tcg_out_label(s, lab1, (tcg_target_long)s->code_ptr);
1184 fd76e73a Richard Henderson
1185 fd76e73a Richard Henderson
    argreg = TCG_REG_R26;
1186 fd76e73a Richard Henderson
    tcg_out_mov(s, argreg--, addr_reg);
1187 fd76e73a Richard Henderson
    if (TARGET_LONG_BITS == 64) {
1188 fd76e73a Richard Henderson
        tcg_out_mov(s, argreg--, addr_reg2);
1189 fd76e73a Richard Henderson
    }
1190 fd76e73a Richard Henderson
1191 fd76e73a Richard Henderson
    switch(opc) {
1192 fd76e73a Richard Henderson
    case 0:
1193 fd76e73a Richard Henderson
        tcg_out_andi(s, argreg--, data_reg, 0xff);
1194 fd76e73a Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
1195 fd76e73a Richard Henderson
        break;
1196 fd76e73a Richard Henderson
    case 1:
1197 fd76e73a Richard Henderson
        tcg_out_andi(s, argreg--, data_reg, 0xffff);
1198 fd76e73a Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
1199 fd76e73a Richard Henderson
        break;
1200 fd76e73a Richard Henderson
    case 2:
1201 fd76e73a Richard Henderson
        tcg_out_mov(s, argreg--, data_reg);
1202 fd76e73a Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
1203 fd76e73a Richard Henderson
        break;
1204 fd76e73a Richard Henderson
    case 3:
1205 fd76e73a Richard Henderson
        /* Because of the alignment required by the 64-bit data argument,
1206 fd76e73a Richard Henderson
           we will always use R23/R24.  Also, we will always run out of
1207 fd76e73a Richard Henderson
           argument registers for storing mem_index, so that will have
1208 fd76e73a Richard Henderson
           to go on the stack.  */
1209 fd76e73a Richard Henderson
        if (mem_index == 0) {
1210 fd76e73a Richard Henderson
            argreg = TCG_REG_R0;
1211 fd76e73a Richard Henderson
        } else {
1212 fd76e73a Richard Henderson
            argreg = TCG_REG_R20;
1213 fd76e73a Richard Henderson
            tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
1214 fd76e73a Richard Henderson
        }
1215 fd76e73a Richard Henderson
        tcg_out_mov(s, TCG_REG_R23, data_reg2);
1216 fd76e73a Richard Henderson
        tcg_out_mov(s, TCG_REG_R24, data_reg);
1217 fd76e73a Richard Henderson
        tcg_out_st(s, TCG_TYPE_I32, argreg, TCG_REG_SP,
1218 fd76e73a Richard Henderson
                   TCG_TARGET_CALL_STACK_OFFSET - 4);
1219 fd76e73a Richard Henderson
        break;
1220 fd76e73a Richard Henderson
    default:
1221 fd76e73a Richard Henderson
        tcg_abort();
1222 fd76e73a Richard Henderson
    }
1223 fd76e73a Richard Henderson
1224 fd76e73a Richard Henderson
    tcg_out_call(s, qemu_st_helpers[s_bits]);
1225 fd76e73a Richard Henderson
1226 f54b3f92 aurel32
    /* label2: */
1227 fd76e73a Richard Henderson
    tcg_out_label(s, lab2, (tcg_target_long)s->code_ptr);
1228 f54b3f92 aurel32
#endif
1229 f54b3f92 aurel32
}
1230 f54b3f92 aurel32
1231 fd76e73a Richard Henderson
static void tcg_out_exit_tb(TCGContext *s, TCGArg arg)
1232 fd76e73a Richard Henderson
{
1233 fd76e73a Richard Henderson
    if (!check_fit_tl(arg, 14)) {
1234 fd76e73a Richard Henderson
        uint32_t hi, lo;
1235 fd76e73a Richard Henderson
        hi = arg & ~0x7ff;
1236 fd76e73a Richard Henderson
        lo = arg & 0x7ff;
1237 fd76e73a Richard Henderson
        if (lo) {
1238 fd76e73a Richard Henderson
            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RET0, hi);
1239 fd76e73a Richard Henderson
            tcg_out32(s, INSN_BV | INSN_R2(TCG_REG_R18));
1240 fd76e73a Richard Henderson
            tcg_out_addi(s, TCG_REG_RET0, lo);
1241 fd76e73a Richard Henderson
            return;
1242 fd76e73a Richard Henderson
        }
1243 fd76e73a Richard Henderson
        arg = hi;
1244 fd76e73a Richard Henderson
    }
1245 fd76e73a Richard Henderson
    tcg_out32(s, INSN_BV | INSN_R2(TCG_REG_R18));
1246 fd76e73a Richard Henderson
    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RET0, arg);
1247 fd76e73a Richard Henderson
}
1248 fd76e73a Richard Henderson
1249 fd76e73a Richard Henderson
static void tcg_out_goto_tb(TCGContext *s, TCGArg arg)
1250 fd76e73a Richard Henderson
{
1251 fd76e73a Richard Henderson
    if (s->tb_jmp_offset) {
1252 fd76e73a Richard Henderson
        /* direct jump method */
1253 fd76e73a Richard Henderson
        fprintf(stderr, "goto_tb direct\n");
1254 fd76e73a Richard Henderson
        tcg_abort();
1255 fd76e73a Richard Henderson
    } else {
1256 fd76e73a Richard Henderson
        /* indirect jump method */
1257 fd76e73a Richard Henderson
        tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, TCG_REG_R0,
1258 fd76e73a Richard Henderson
                   (tcg_target_long)(s->tb_next + arg));
1259 fd76e73a Richard Henderson
        tcg_out32(s, INSN_BV_N | INSN_R2(TCG_REG_R20));
1260 fd76e73a Richard Henderson
    }
1261 fd76e73a Richard Henderson
    s->tb_next_offset[arg] = s->code_ptr - s->code_buf;
1262 fd76e73a Richard Henderson
}
1263 fd76e73a Richard Henderson
1264 a9751609 Richard Henderson
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1265 f54b3f92 aurel32
                              const int *const_args)
1266 f54b3f92 aurel32
{
1267 f54b3f92 aurel32
    switch (opc) {
1268 f54b3f92 aurel32
    case INDEX_op_exit_tb:
1269 fd76e73a Richard Henderson
        tcg_out_exit_tb(s, args[0]);
1270 f54b3f92 aurel32
        break;
1271 f54b3f92 aurel32
    case INDEX_op_goto_tb:
1272 fd76e73a Richard Henderson
        tcg_out_goto_tb(s, args[0]);
1273 f54b3f92 aurel32
        break;
1274 fd76e73a Richard Henderson
1275 f54b3f92 aurel32
    case INDEX_op_call:
1276 fd76e73a Richard Henderson
        if (const_args[0]) {
1277 fd76e73a Richard Henderson
            tcg_out_call(s, (void *)args[0]);
1278 fd76e73a Richard Henderson
        } else {
1279 fd76e73a Richard Henderson
            tcg_out32(s, INSN_BLE_SR4 | INSN_R2(args[0]));
1280 fd76e73a Richard Henderson
            tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
1281 fd76e73a Richard Henderson
        }
1282 f54b3f92 aurel32
        break;
1283 fd76e73a Richard Henderson
1284 f54b3f92 aurel32
    case INDEX_op_jmp:
1285 f54b3f92 aurel32
        fprintf(stderr, "unimplemented jmp\n");
1286 f54b3f92 aurel32
        tcg_abort();
1287 f54b3f92 aurel32
        break;
1288 fd76e73a Richard Henderson
1289 f54b3f92 aurel32
    case INDEX_op_br:
1290 fd76e73a Richard Henderson
        tcg_out_branch(s, args[0], 1);
1291 f54b3f92 aurel32
        break;
1292 fd76e73a Richard Henderson
1293 f54b3f92 aurel32
    case INDEX_op_movi_i32:
1294 f54b3f92 aurel32
        tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
1295 f54b3f92 aurel32
        break;
1296 f54b3f92 aurel32
1297 f54b3f92 aurel32
    case INDEX_op_ld8u_i32:
1298 fd76e73a Richard Henderson
        tcg_out_ldst(s, args[0], args[1], args[2], INSN_LDB);
1299 f54b3f92 aurel32
        break;
1300 f54b3f92 aurel32
    case INDEX_op_ld8s_i32:
1301 fd76e73a Richard Henderson
        tcg_out_ldst(s, args[0], args[1], args[2], INSN_LDB);
1302 f54b3f92 aurel32
        tcg_out_ext8s(s, args[0], args[0]);
1303 f54b3f92 aurel32
        break;
1304 f54b3f92 aurel32
    case INDEX_op_ld16u_i32:
1305 fd76e73a Richard Henderson
        tcg_out_ldst(s, args[0], args[1], args[2], INSN_LDH);
1306 f54b3f92 aurel32
        break;
1307 f54b3f92 aurel32
    case INDEX_op_ld16s_i32:
1308 fd76e73a Richard Henderson
        tcg_out_ldst(s, args[0], args[1], args[2], INSN_LDH);
1309 f54b3f92 aurel32
        tcg_out_ext16s(s, args[0], args[0]);
1310 f54b3f92 aurel32
        break;
1311 f54b3f92 aurel32
    case INDEX_op_ld_i32:
1312 fd76e73a Richard Henderson
        tcg_out_ldst(s, args[0], args[1], args[2], INSN_LDW);
1313 f54b3f92 aurel32
        break;
1314 f54b3f92 aurel32
1315 f54b3f92 aurel32
    case INDEX_op_st8_i32:
1316 fd76e73a Richard Henderson
        tcg_out_ldst(s, args[0], args[1], args[2], INSN_STB);
1317 f54b3f92 aurel32
        break;
1318 f54b3f92 aurel32
    case INDEX_op_st16_i32:
1319 fd76e73a Richard Henderson
        tcg_out_ldst(s, args[0], args[1], args[2], INSN_STH);
1320 f54b3f92 aurel32
        break;
1321 f54b3f92 aurel32
    case INDEX_op_st_i32:
1322 fd76e73a Richard Henderson
        tcg_out_ldst(s, args[0], args[1], args[2], INSN_STW);
1323 fd76e73a Richard Henderson
        break;
1324 fd76e73a Richard Henderson
1325 fd76e73a Richard Henderson
    case INDEX_op_add_i32:
1326 fd76e73a Richard Henderson
        if (const_args[2]) {
1327 fd76e73a Richard Henderson
            tcg_out_addi2(s, args[0], args[1], args[2]);
1328 fd76e73a Richard Henderson
        } else {
1329 fd76e73a Richard Henderson
            tcg_out_arith(s, args[0], args[1], args[2], INSN_ADDL);
1330 fd76e73a Richard Henderson
        }
1331 f54b3f92 aurel32
        break;
1332 f54b3f92 aurel32
1333 f54b3f92 aurel32
    case INDEX_op_sub_i32:
1334 fd76e73a Richard Henderson
        if (const_args[1]) {
1335 fd76e73a Richard Henderson
            if (const_args[2]) {
1336 fd76e73a Richard Henderson
                tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1] - args[2]);
1337 fd76e73a Richard Henderson
            } else {
1338 fd76e73a Richard Henderson
                /* Recall that SUBI is a reversed subtract.  */
1339 fd76e73a Richard Henderson
                tcg_out_arithi(s, args[0], args[2], args[1], INSN_SUBI);
1340 fd76e73a Richard Henderson
            }
1341 fd76e73a Richard Henderson
        } else if (const_args[2]) {
1342 fd76e73a Richard Henderson
            tcg_out_addi2(s, args[0], args[1], -args[2]);
1343 fd76e73a Richard Henderson
        } else {
1344 fd76e73a Richard Henderson
            tcg_out_arith(s, args[0], args[1], args[2], INSN_SUB);
1345 fd76e73a Richard Henderson
        }
1346 fd76e73a Richard Henderson
        break;
1347 fd76e73a Richard Henderson
1348 f54b3f92 aurel32
    case INDEX_op_and_i32:
1349 fd76e73a Richard Henderson
        if (const_args[2]) {
1350 fd76e73a Richard Henderson
            tcg_out_andi(s, args[0], args[1], args[2]);
1351 fd76e73a Richard Henderson
        } else {
1352 fd76e73a Richard Henderson
            tcg_out_arith(s, args[0], args[1], args[2], INSN_AND);
1353 fd76e73a Richard Henderson
        }
1354 fd76e73a Richard Henderson
        break;
1355 fd76e73a Richard Henderson
1356 f54b3f92 aurel32
    case INDEX_op_or_i32:
1357 fd76e73a Richard Henderson
        if (const_args[2]) {
1358 fd76e73a Richard Henderson
            tcg_out_ori(s, args[0], args[1], args[2]);
1359 fd76e73a Richard Henderson
        } else {
1360 fd76e73a Richard Henderson
            tcg_out_arith(s, args[0], args[1], args[2], INSN_OR);
1361 fd76e73a Richard Henderson
        }
1362 fd76e73a Richard Henderson
        break;
1363 fd76e73a Richard Henderson
1364 f54b3f92 aurel32
    case INDEX_op_xor_i32:
1365 fd76e73a Richard Henderson
        tcg_out_arith(s, args[0], args[1], args[2], INSN_XOR);
1366 fd76e73a Richard Henderson
        break;
1367 fd76e73a Richard Henderson
1368 fd76e73a Richard Henderson
    case INDEX_op_andc_i32:
1369 fd76e73a Richard Henderson
        if (const_args[2]) {
1370 fd76e73a Richard Henderson
            tcg_out_andi(s, args[0], args[1], ~args[2]);
1371 fd76e73a Richard Henderson
        } else {
1372 fd76e73a Richard Henderson
            tcg_out_arith(s, args[0], args[1], args[2], INSN_ANDCM);
1373 fd76e73a Richard Henderson
        }
1374 fd76e73a Richard Henderson
        break;
1375 f54b3f92 aurel32
1376 f54b3f92 aurel32
    case INDEX_op_shl_i32:
1377 fd76e73a Richard Henderson
        if (const_args[2]) {
1378 fd76e73a Richard Henderson
            tcg_out_shli(s, args[0], args[1], args[2]);
1379 fd76e73a Richard Henderson
        } else {
1380 fd76e73a Richard Henderson
            tcg_out_shl(s, args[0], args[1], args[2]);
1381 fd76e73a Richard Henderson
        }
1382 f54b3f92 aurel32
        break;
1383 fd76e73a Richard Henderson
1384 f54b3f92 aurel32
    case INDEX_op_shr_i32:
1385 fd76e73a Richard Henderson
        if (const_args[2]) {
1386 fd76e73a Richard Henderson
            tcg_out_shri(s, args[0], args[1], args[2]);
1387 fd76e73a Richard Henderson
        } else {
1388 fd76e73a Richard Henderson
            tcg_out_shr(s, args[0], args[1], args[2]);
1389 fd76e73a Richard Henderson
        }
1390 f54b3f92 aurel32
        break;
1391 fd76e73a Richard Henderson
1392 f54b3f92 aurel32
    case INDEX_op_sar_i32:
1393 fd76e73a Richard Henderson
        if (const_args[2]) {
1394 fd76e73a Richard Henderson
            tcg_out_sari(s, args[0], args[1], args[2]);
1395 fd76e73a Richard Henderson
        } else {
1396 fd76e73a Richard Henderson
            tcg_out_sar(s, args[0], args[1], args[2]);
1397 fd76e73a Richard Henderson
        }
1398 fd76e73a Richard Henderson
        break;
1399 fd76e73a Richard Henderson
1400 fd76e73a Richard Henderson
    case INDEX_op_rotl_i32:
1401 fd76e73a Richard Henderson
        if (const_args[2]) {
1402 fd76e73a Richard Henderson
            tcg_out_rotli(s, args[0], args[1], args[2]);
1403 fd76e73a Richard Henderson
        } else {
1404 fd76e73a Richard Henderson
            tcg_out_rotl(s, args[0], args[1], args[2]);
1405 fd76e73a Richard Henderson
        }
1406 fd76e73a Richard Henderson
        break;
1407 fd76e73a Richard Henderson
1408 fd76e73a Richard Henderson
    case INDEX_op_rotr_i32:
1409 fd76e73a Richard Henderson
        if (const_args[2]) {
1410 fd76e73a Richard Henderson
            tcg_out_rotri(s, args[0], args[1], args[2]);
1411 fd76e73a Richard Henderson
        } else {
1412 fd76e73a Richard Henderson
            tcg_out_rotr(s, args[0], args[1], args[2]);
1413 fd76e73a Richard Henderson
        }
1414 f54b3f92 aurel32
        break;
1415 f54b3f92 aurel32
1416 f54b3f92 aurel32
    case INDEX_op_mul_i32:
1417 fd76e73a Richard Henderson
        tcg_out_xmpyu(s, args[0], TCG_REG_R0, args[1], args[2]);
1418 f54b3f92 aurel32
        break;
1419 f54b3f92 aurel32
    case INDEX_op_mulu2_i32:
1420 fd76e73a Richard Henderson
        tcg_out_xmpyu(s, args[0], args[1], args[2], args[3]);
1421 f54b3f92 aurel32
        break;
1422 fd76e73a Richard Henderson
1423 fd76e73a Richard Henderson
    case INDEX_op_bswap16_i32:
1424 fd76e73a Richard Henderson
        tcg_out_bswap16(s, args[0], args[1], 0);
1425 f54b3f92 aurel32
        break;
1426 fd76e73a Richard Henderson
    case INDEX_op_bswap32_i32:
1427 fd76e73a Richard Henderson
        tcg_out_bswap32(s, args[0], args[1], TCG_REG_R20);
1428 fd76e73a Richard Henderson
        break;
1429 fd76e73a Richard Henderson
1430 fd76e73a Richard Henderson
    case INDEX_op_not_i32:
1431 fd76e73a Richard Henderson
        tcg_out_arithi(s, args[0], args[1], -1, INSN_SUBI);
1432 fd76e73a Richard Henderson
        break;
1433 fd76e73a Richard Henderson
    case INDEX_op_ext8s_i32:
1434 fd76e73a Richard Henderson
        tcg_out_ext8s(s, args[0], args[1]);
1435 fd76e73a Richard Henderson
        break;
1436 fd76e73a Richard Henderson
    case INDEX_op_ext16s_i32:
1437 fd76e73a Richard Henderson
        tcg_out_ext16s(s, args[0], args[1]);
1438 fd76e73a Richard Henderson
        break;
1439 fd76e73a Richard Henderson
1440 fd76e73a Richard Henderson
    /* These three correspond exactly to the fallback implementation.
1441 fd76e73a Richard Henderson
       But by including them we reduce the number of TCG ops that
1442 fd76e73a Richard Henderson
       need to be generated, and these opcodes are fairly common.  */
1443 fd76e73a Richard Henderson
    case INDEX_op_neg_i32:
1444 fd76e73a Richard Henderson
        tcg_out_arith(s, args[0], TCG_REG_R0, args[1], INSN_SUB);
1445 fd76e73a Richard Henderson
        break;
1446 fd76e73a Richard Henderson
    case INDEX_op_ext8u_i32:
1447 fd76e73a Richard Henderson
        tcg_out_andi(s, args[0], args[1], 0xff);
1448 fd76e73a Richard Henderson
        break;
1449 fd76e73a Richard Henderson
    case INDEX_op_ext16u_i32:
1450 fd76e73a Richard Henderson
        tcg_out_andi(s, args[0], args[1], 0xffff);
1451 f54b3f92 aurel32
        break;
1452 f54b3f92 aurel32
1453 f54b3f92 aurel32
    case INDEX_op_brcond_i32:
1454 fd76e73a Richard Henderson
        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], args[3]);
1455 fd76e73a Richard Henderson
        break;
1456 fd76e73a Richard Henderson
    case INDEX_op_brcond2_i32:
1457 fd76e73a Richard Henderson
        tcg_out_brcond2(s, args[4], args[0], args[1],
1458 fd76e73a Richard Henderson
                        args[2], const_args[2],
1459 fd76e73a Richard Henderson
                        args[3], const_args[3], args[5]);
1460 fd76e73a Richard Henderson
        break;
1461 fd76e73a Richard Henderson
1462 fd76e73a Richard Henderson
    case INDEX_op_setcond_i32:
1463 fd76e73a Richard Henderson
        tcg_out_setcond(s, args[3], args[0], args[1], args[2], const_args[2]);
1464 fd76e73a Richard Henderson
        break;
1465 fd76e73a Richard Henderson
    case INDEX_op_setcond2_i32:
1466 fd76e73a Richard Henderson
        tcg_out_setcond2(s, args[5], args[0], args[1], args[2],
1467 fd76e73a Richard Henderson
                         args[3], const_args[3], args[4], const_args[4]);
1468 fd76e73a Richard Henderson
        break;
1469 fd76e73a Richard Henderson
1470 fd76e73a Richard Henderson
    case INDEX_op_add2_i32:
1471 91493631 Richard Henderson
        tcg_out_add2(s, args[0], args[1], args[2], args[3],
1472 91493631 Richard Henderson
                     args[4], args[5], const_args[4]);
1473 fd76e73a Richard Henderson
        break;
1474 fd76e73a Richard Henderson
1475 fd76e73a Richard Henderson
    case INDEX_op_sub2_i32:
1476 91493631 Richard Henderson
        tcg_out_sub2(s, args[0], args[1], args[2], args[3],
1477 91493631 Richard Henderson
                     args[4], args[5], const_args[2], const_args[4]);
1478 f54b3f92 aurel32
        break;
1479 f54b3f92 aurel32
1480 f54b3f92 aurel32
    case INDEX_op_qemu_ld8u:
1481 f54b3f92 aurel32
        tcg_out_qemu_ld(s, args, 0);
1482 f54b3f92 aurel32
        break;
1483 f54b3f92 aurel32
    case INDEX_op_qemu_ld8s:
1484 f54b3f92 aurel32
        tcg_out_qemu_ld(s, args, 0 | 4);
1485 f54b3f92 aurel32
        break;
1486 f54b3f92 aurel32
    case INDEX_op_qemu_ld16u:
1487 f54b3f92 aurel32
        tcg_out_qemu_ld(s, args, 1);
1488 f54b3f92 aurel32
        break;
1489 f54b3f92 aurel32
    case INDEX_op_qemu_ld16s:
1490 f54b3f92 aurel32
        tcg_out_qemu_ld(s, args, 1 | 4);
1491 f54b3f92 aurel32
        break;
1492 86feb1c8 Richard Henderson
    case INDEX_op_qemu_ld32:
1493 f54b3f92 aurel32
        tcg_out_qemu_ld(s, args, 2);
1494 f54b3f92 aurel32
        break;
1495 fd76e73a Richard Henderson
    case INDEX_op_qemu_ld64:
1496 fd76e73a Richard Henderson
        tcg_out_qemu_ld(s, args, 3);
1497 fd76e73a Richard Henderson
        break;
1498 f54b3f92 aurel32
1499 f54b3f92 aurel32
    case INDEX_op_qemu_st8:
1500 f54b3f92 aurel32
        tcg_out_qemu_st(s, args, 0);
1501 f54b3f92 aurel32
        break;
1502 f54b3f92 aurel32
    case INDEX_op_qemu_st16:
1503 f54b3f92 aurel32
        tcg_out_qemu_st(s, args, 1);
1504 f54b3f92 aurel32
        break;
1505 f54b3f92 aurel32
    case INDEX_op_qemu_st32:
1506 f54b3f92 aurel32
        tcg_out_qemu_st(s, args, 2);
1507 f54b3f92 aurel32
        break;
1508 fd76e73a Richard Henderson
    case INDEX_op_qemu_st64:
1509 fd76e73a Richard Henderson
        tcg_out_qemu_st(s, args, 3);
1510 fd76e73a Richard Henderson
        break;
1511 f54b3f92 aurel32
1512 f54b3f92 aurel32
    default:
1513 f54b3f92 aurel32
        fprintf(stderr, "unknown opcode 0x%x\n", opc);
1514 f54b3f92 aurel32
        tcg_abort();
1515 f54b3f92 aurel32
    }
1516 f54b3f92 aurel32
}
1517 f54b3f92 aurel32
1518 f54b3f92 aurel32
static const TCGTargetOpDef hppa_op_defs[] = {
1519 f54b3f92 aurel32
    { INDEX_op_exit_tb, { } },
1520 f54b3f92 aurel32
    { INDEX_op_goto_tb, { } },
1521 f54b3f92 aurel32
1522 fd76e73a Richard Henderson
    { INDEX_op_call, { "ri" } },
1523 f54b3f92 aurel32
    { INDEX_op_jmp, { "r" } },
1524 f54b3f92 aurel32
    { INDEX_op_br, { } },
1525 f54b3f92 aurel32
1526 f54b3f92 aurel32
    { INDEX_op_mov_i32, { "r", "r" } },
1527 f54b3f92 aurel32
    { INDEX_op_movi_i32, { "r" } },
1528 fd76e73a Richard Henderson
1529 f54b3f92 aurel32
    { INDEX_op_ld8u_i32, { "r", "r" } },
1530 f54b3f92 aurel32
    { INDEX_op_ld8s_i32, { "r", "r" } },
1531 f54b3f92 aurel32
    { INDEX_op_ld16u_i32, { "r", "r" } },
1532 f54b3f92 aurel32
    { INDEX_op_ld16s_i32, { "r", "r" } },
1533 f54b3f92 aurel32
    { INDEX_op_ld_i32, { "r", "r" } },
1534 fd76e73a Richard Henderson
    { INDEX_op_st8_i32, { "rZ", "r" } },
1535 fd76e73a Richard Henderson
    { INDEX_op_st16_i32, { "rZ", "r" } },
1536 fd76e73a Richard Henderson
    { INDEX_op_st_i32, { "rZ", "r" } },
1537 fd76e73a Richard Henderson
1538 fd76e73a Richard Henderson
    { INDEX_op_add_i32, { "r", "rZ", "ri" } },
1539 fd76e73a Richard Henderson
    { INDEX_op_sub_i32, { "r", "rI", "ri" } },
1540 fd76e73a Richard Henderson
    { INDEX_op_and_i32, { "r", "rZ", "ri" } },
1541 fd76e73a Richard Henderson
    { INDEX_op_or_i32, { "r", "rZ", "ri" } },
1542 fd76e73a Richard Henderson
    { INDEX_op_xor_i32, { "r", "rZ", "rZ" } },
1543 fd76e73a Richard Henderson
    { INDEX_op_andc_i32, { "r", "rZ", "ri" } },
1544 fd76e73a Richard Henderson
1545 fd76e73a Richard Henderson
    { INDEX_op_mul_i32, { "r", "r", "r" } },
1546 fd76e73a Richard Henderson
    { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
1547 f54b3f92 aurel32
1548 fd76e73a Richard Henderson
    { INDEX_op_shl_i32, { "r", "r", "ri" } },
1549 fd76e73a Richard Henderson
    { INDEX_op_shr_i32, { "r", "r", "ri" } },
1550 fd76e73a Richard Henderson
    { INDEX_op_sar_i32, { "r", "r", "ri" } },
1551 fd76e73a Richard Henderson
    { INDEX_op_rotl_i32, { "r", "r", "ri" } },
1552 fd76e73a Richard Henderson
    { INDEX_op_rotr_i32, { "r", "r", "ri" } },
1553 f54b3f92 aurel32
1554 fd76e73a Richard Henderson
    { INDEX_op_bswap16_i32, { "r", "r" } },
1555 fd76e73a Richard Henderson
    { INDEX_op_bswap32_i32, { "r", "r" } },
1556 fd76e73a Richard Henderson
    { INDEX_op_neg_i32, { "r", "r" } },
1557 fd76e73a Richard Henderson
    { INDEX_op_not_i32, { "r", "r" } },
1558 f54b3f92 aurel32
1559 fd76e73a Richard Henderson
    { INDEX_op_ext8s_i32, { "r", "r" } },
1560 fd76e73a Richard Henderson
    { INDEX_op_ext8u_i32, { "r", "r" } },
1561 fd76e73a Richard Henderson
    { INDEX_op_ext16s_i32, { "r", "r" } },
1562 fd76e73a Richard Henderson
    { INDEX_op_ext16u_i32, { "r", "r" } },
1563 fd76e73a Richard Henderson
1564 fd76e73a Richard Henderson
    { INDEX_op_brcond_i32, { "rZ", "rJ" } },
1565 fd76e73a Richard Henderson
    { INDEX_op_brcond2_i32,  { "rZ", "rZ", "rJ", "rJ" } },
1566 fd76e73a Richard Henderson
1567 fd76e73a Richard Henderson
    { INDEX_op_setcond_i32, { "r", "rZ", "rI" } },
1568 fd76e73a Richard Henderson
    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rI", "rI" } },
1569 fd76e73a Richard Henderson
1570 fd76e73a Richard Henderson
    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rI", "rZ" } },
1571 91493631 Richard Henderson
    { INDEX_op_sub2_i32, { "r", "r", "rI", "rZ", "rK", "rZ" } },
1572 f54b3f92 aurel32
1573 f54b3f92 aurel32
#if TARGET_LONG_BITS == 32
1574 f54b3f92 aurel32
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1575 f54b3f92 aurel32
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1576 f54b3f92 aurel32
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1577 f54b3f92 aurel32
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1578 86feb1c8 Richard Henderson
    { INDEX_op_qemu_ld32, { "r", "L" } },
1579 f54b3f92 aurel32
    { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1580 f54b3f92 aurel32
1581 fd76e73a Richard Henderson
    { INDEX_op_qemu_st8, { "LZ", "L" } },
1582 fd76e73a Richard Henderson
    { INDEX_op_qemu_st16, { "LZ", "L" } },
1583 fd76e73a Richard Henderson
    { INDEX_op_qemu_st32, { "LZ", "L" } },
1584 fd76e73a Richard Henderson
    { INDEX_op_qemu_st64, { "LZ", "LZ", "L" } },
1585 f54b3f92 aurel32
#else
1586 f54b3f92 aurel32
    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
1587 f54b3f92 aurel32
    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
1588 f54b3f92 aurel32
    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
1589 f54b3f92 aurel32
    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1590 86feb1c8 Richard Henderson
    { INDEX_op_qemu_ld32, { "r", "L", "L" } },
1591 f54b3f92 aurel32
    { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
1592 f54b3f92 aurel32
1593 fd76e73a Richard Henderson
    { INDEX_op_qemu_st8, { "LZ", "L", "L" } },
1594 fd76e73a Richard Henderson
    { INDEX_op_qemu_st16, { "LZ", "L", "L" } },
1595 fd76e73a Richard Henderson
    { INDEX_op_qemu_st32, { "LZ", "L", "L" } },
1596 fd76e73a Richard Henderson
    { INDEX_op_qemu_st64, { "LZ", "LZ", "L", "L" } },
1597 f54b3f92 aurel32
#endif
1598 f54b3f92 aurel32
    { -1 },
1599 f54b3f92 aurel32
};
1600 f54b3f92 aurel32
1601 fd76e73a Richard Henderson
static int tcg_target_callee_save_regs[] = {
1602 fd76e73a Richard Henderson
    /* R2, the return address register, is saved specially
1603 fd76e73a Richard Henderson
       in the caller's frame.  */
1604 fd76e73a Richard Henderson
    /* R3, the frame pointer, is not currently modified.  */
1605 fd76e73a Richard Henderson
    TCG_REG_R4,
1606 fd76e73a Richard Henderson
    TCG_REG_R5,
1607 fd76e73a Richard Henderson
    TCG_REG_R6,
1608 fd76e73a Richard Henderson
    TCG_REG_R7,
1609 fd76e73a Richard Henderson
    TCG_REG_R8,
1610 fd76e73a Richard Henderson
    TCG_REG_R9,
1611 fd76e73a Richard Henderson
    TCG_REG_R10,
1612 fd76e73a Richard Henderson
    TCG_REG_R11,
1613 fd76e73a Richard Henderson
    TCG_REG_R12,
1614 fd76e73a Richard Henderson
    TCG_REG_R13,
1615 fd76e73a Richard Henderson
    TCG_REG_R14,
1616 fd76e73a Richard Henderson
    TCG_REG_R15,
1617 fd76e73a Richard Henderson
    TCG_REG_R16,
1618 fd76e73a Richard Henderson
    /* R17 is the global env, so no need to save.  */
1619 fd76e73a Richard Henderson
    TCG_REG_R18
1620 fd76e73a Richard Henderson
};
1621 fd76e73a Richard Henderson
1622 fd76e73a Richard Henderson
void tcg_target_qemu_prologue(TCGContext *s)
1623 fd76e73a Richard Henderson
{
1624 fd76e73a Richard Henderson
    int frame_size, i;
1625 fd76e73a Richard Henderson
1626 fd76e73a Richard Henderson
    /* Allocate space for the fixed frame marker.  */
1627 fd76e73a Richard Henderson
    frame_size = -TCG_TARGET_CALL_STACK_OFFSET;
1628 fd76e73a Richard Henderson
    frame_size += TCG_TARGET_STATIC_CALL_ARGS_SIZE;
1629 fd76e73a Richard Henderson
1630 fd76e73a Richard Henderson
    /* Allocate space for the saved registers.  */
1631 fd76e73a Richard Henderson
    frame_size += ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
1632 fd76e73a Richard Henderson
1633 fd76e73a Richard Henderson
    /* Align the allocated space.  */
1634 fd76e73a Richard Henderson
    frame_size = ((frame_size + TCG_TARGET_STACK_ALIGN - 1)
1635 fd76e73a Richard Henderson
                  & -TCG_TARGET_STACK_ALIGN);
1636 fd76e73a Richard Henderson
1637 fd76e73a Richard Henderson
    /* The return address is stored in the caller's frame.  */
1638 fd76e73a Richard Henderson
    tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_RP, TCG_REG_SP, -20);
1639 fd76e73a Richard Henderson
1640 fd76e73a Richard Henderson
    /* Allocate stack frame, saving the first register at the same time.  */
1641 fd76e73a Richard Henderson
    tcg_out_ldst(s, tcg_target_callee_save_regs[0],
1642 fd76e73a Richard Henderson
                 TCG_REG_SP, frame_size, INSN_STWM);
1643 fd76e73a Richard Henderson
1644 fd76e73a Richard Henderson
    /* Save all callee saved registers.  */
1645 fd76e73a Richard Henderson
    for (i = 1; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1646 fd76e73a Richard Henderson
        tcg_out_st(s, TCG_TYPE_PTR, tcg_target_callee_save_regs[i],
1647 fd76e73a Richard Henderson
                   TCG_REG_SP, -frame_size + i * 4);
1648 fd76e73a Richard Henderson
    }
1649 fd76e73a Richard Henderson
1650 fd76e73a Richard Henderson
    if (GUEST_BASE != 0) {
1651 fd76e73a Richard Henderson
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
1652 fd76e73a Richard Henderson
    }
1653 fd76e73a Richard Henderson
1654 fd76e73a Richard Henderson
    /* Jump to TB, and adjust R18 to be the return address.  */
1655 fd76e73a Richard Henderson
    tcg_out32(s, INSN_BLE_SR4 | INSN_R2(TCG_REG_R26));
1656 fd76e73a Richard Henderson
    tcg_out_mov(s, TCG_REG_R18, TCG_REG_R31);
1657 fd76e73a Richard Henderson
1658 fd76e73a Richard Henderson
    /* Restore callee saved registers.  */
1659 fd76e73a Richard Henderson
    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_RP, TCG_REG_SP, -frame_size - 20);
1660 fd76e73a Richard Henderson
    for (i = 1; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1661 fd76e73a Richard Henderson
        tcg_out_ld(s, TCG_TYPE_PTR, tcg_target_callee_save_regs[i],
1662 fd76e73a Richard Henderson
                   TCG_REG_SP, -frame_size + i * 4);
1663 fd76e73a Richard Henderson
    }
1664 fd76e73a Richard Henderson
1665 fd76e73a Richard Henderson
    /* Deallocate stack frame and return.  */
1666 fd76e73a Richard Henderson
    tcg_out32(s, INSN_BV | INSN_R2(TCG_REG_RP));
1667 fd76e73a Richard Henderson
    tcg_out_ldst(s, tcg_target_callee_save_regs[0],
1668 fd76e73a Richard Henderson
                 TCG_REG_SP, -frame_size, INSN_LDWM);
1669 fd76e73a Richard Henderson
}
1670 fd76e73a Richard Henderson
1671 f54b3f92 aurel32
void tcg_target_init(TCGContext *s)
1672 f54b3f92 aurel32
{
1673 f54b3f92 aurel32
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1674 fd76e73a Richard Henderson
1675 fd76e73a Richard Henderson
    tcg_regset_clear(tcg_target_call_clobber_regs);
1676 fd76e73a Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R20);
1677 fd76e73a Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R21);
1678 fd76e73a Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R22);
1679 fd76e73a Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R23);
1680 fd76e73a Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R24);
1681 fd76e73a Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R25);
1682 fd76e73a Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R26);
1683 fd76e73a Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RET0);
1684 fd76e73a Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RET1);
1685 f54b3f92 aurel32
1686 f54b3f92 aurel32
    tcg_regset_clear(s->reserved_regs);
1687 f54b3f92 aurel32
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);  /* hardwired to zero */
1688 f54b3f92 aurel32
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);  /* addil target */
1689 f54b3f92 aurel32
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RP);  /* link register */
1690 f54b3f92 aurel32
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R3);  /* frame pointer */
1691 f54b3f92 aurel32
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R18); /* return pointer */
1692 f54b3f92 aurel32
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R19); /* clobbered w/o pic */
1693 f54b3f92 aurel32
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R20); /* reserved */
1694 f54b3f92 aurel32
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_DP);  /* data pointer */
1695 f54b3f92 aurel32
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);  /* stack pointer */
1696 f54b3f92 aurel32
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */
1697 fd76e73a Richard Henderson
    if (GUEST_BASE != 0) {
1698 fd76e73a Richard Henderson
        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1699 fd76e73a Richard Henderson
    }
1700 f54b3f92 aurel32
1701 f54b3f92 aurel32
    tcg_add_target_add_op_defs(hppa_op_defs);
1702 f54b3f92 aurel32
}