1 /******************************** -*- C -*- **************************** 2 * 3 * Platform-independent layer (Sparc version) 4 * 5 ***********************************************************************/ 6 7 8 /*********************************************************************** 9 * 10 * Copyright 2000, 2001, 2002 Free Software Foundation, Inc. 11 * Written by Paolo Bonzini. 12 * 13 * This file is part of GNU lightning. 14 * 15 * GNU lightning is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU Lesser General Public License as published 17 * by the Free Software Foundation; either version 2.1, or (at your option) 18 * any later version. 19 * 20 * GNU lightning is distributed in the hope that it will be useful, but 21 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 22 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 23 * License for more details. 24 * 25 * You should have received a copy of the GNU Lesser General Public License 26 * along with GNU lightning; see the file COPYING.LESSER; if not, write to the 27 * Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 28 * MA 02110-1301, USA. 29 * 30 ***********************************************************************/ 31 32 33 #ifndef __lightning_core_h 34 #define __lightning_core_h 35 36 #define JIT_R_NUM 3 37 #define JIT_V_NUM 6 38 #define JIT_R(i) ((i) ? _Rl((i) - 1) : _Rg(2)) 39 #define JIT_V(i) _Rl((i)+2) 40 41 #define JIT_BIG _Rg(1) /* %g1 used to make 32-bit operands */ 42 #define JIT_BIG2 _Ro(7) /* %o7 used to make 32-bit compare operands */ 43 #define JIT_SP _Ro(6) 44 #define JIT_RZERO _Rg(0) 45 #define JIT_RET _Ri(0) 46 47 /* Delay slot scheduling: jmp generates branches with annulled delay 48 * slots; we toggle the annul bit if we can fill the slot. CALLs and 49 * cond. branches have a different meaning for the annul bit, so we 50 * automatically generate a NOP and eventually copy the delay insn onto 51 * it. Delay slots in RET are already used for RESTORE, so we don't 52 * schedule them. 53 * 54 * ,--- _jit.x.pc 55 * insn X X before 56 * cmp branch insn X X after (branch) 57 * `--- _jit.x.pc 58 * call insn insn X after (call) 59 * `--- _jit.x.pc 60 */ 61 62 struct jit_local_state { 63 int nextarg_put; /* Next %o reg. to be written */ 64 int nextarg_get; /* Next %i reg. to be read */ 65 jit_insn delay; 66 }; 67 68 #define jit_fill_delay_after(branch) (_jitl.delay = *--_jit.x.pc, \ 69 ((branch) == _jit.x.pc /* check if NOP was inserted */ \ 70 ? (_jit.x.pc[-1] ^= 1<<29) /* no if branch, toggle annul bit */ \ 71 : (_jit.x.pc[-1] = _jitl.delay)), /* yes if call, replace NOP with delay insn */ \ 72 *_jit.x.pc = _jitl.delay, _jit.x.pc - 1) /* return addr of delay insn */ 73 74 /* If possible, use the `small' instruction (rs, imm, rd) 75 * else load imm into %l6 and use the `big' instruction (rs, %l6, rd) 76 * jit_chk_imm2 uses %l7 instead of %l6 to avoid conflicts when using delay slots 77 */ 78 #define jit_chk_imm(imm, small, big) (_siP(13,(imm)) ? (small) : (SETir((imm), JIT_BIG), (big)) ) 79 #define jit_chk_imm2(imm, small, big) (_siP(13,(imm)) ? (small) : (SETir((imm), JIT_BIG2), (big)) ) 80 81 /* Helper macros for branches */ 82 #define jit_branchi(rs, is, jmp, nop) (jit_chk_imm2(is, CMPri(rs, is), CMPrr(rs, JIT_BIG2)), jmp, nop, _jit.x.pc - 1) 83 #define jit_branchr(s1, s2, jmp, nop) ( CMPrr(s1, s2), jmp, nop, _jit.x.pc - 1) 84 85 /* Helper macros for boolean tests -- delay slot sets d to 1; 86 * taken branch leaves it to 1, not-taken branch resets it to 0 */ 87 #define jit_booli(d, rs, is, jmp) (jit_chk_imm (is, CMPri(rs, is), CMPrr(rs, JIT_BIG)), jmp, MOVir(1, (d)), MOVir(0, (d))) 88 #define jit_boolr(d, s1, s2, jmp) ( CMPrr(s1, s2), jmp, MOVir(1, (d)), MOVir(0, (d))) 89 90 /* Helper macros for division 91 * The architecture specifies that there must be 3 instructions between * 92 * a y register write and a use of it for correct results. */ 93 #define jit_prepare_y(rs, is) (SRArir(rs, 31, JIT_BIG), WRri(JIT_BIG, _y), NOP(), NOP(), NOP(), _jit.x.pc -= jit_immsize(is)) 94 #define jit_clr_y(rs, is) ( WRri(0, _y), NOP(), NOP(), NOP(), _jit.x.pc -= jit_immsize(is)) 95 96 #define jit_modr(jit_div, jit_mul, d, s1, s2) \ 97 (jit_div (JIT_BIG, s1, s2), \ 98 jit_mul (JIT_BIG, JIT_BIG, s2), \ 99 jit_subr_i (d, s1, JIT_BIG)) 100 101 #define jit_modi(jit_divi, jit_muli, jit_divr, jit_mulr, d, rs, is) \ 102 (_siP(13,(imm)) \ 103 ? (jit_divi (JIT_BIG, rs, is), \ 104 jit_muli (JIT_BIG, JIT_BIG, is), \ 105 jit_subr_i (d, rs, JIT_BIG)) \ 106 : (SETir ((is), JIT_BIG2), \ 107 jit_modr (jit_divr, jit_mulr, d, rs, JIT_BIG2))) 108 109 /* How many instruction are needed to put imm in a register. */ 110 #define jit_immsize(imm) (!(imm) ? 0 : \ 111 (!_siP((imm), 13) && ((imm) & 0x3ff) ? 2 : 1)) 112 113 114 /* branch instructions return the address of the *delay* instruction -- this 115 * is just a helper macro that makes jit_patch more readable. 116 */ 117 #define jit_patch_(jump_pc,pv) \ 118 (*jump_pc &= ~_MASK(22), \ 119 *jump_pc |= ((_jit_UL((pv)) - _jit_UL(jump_pc)) >> 2) & _MASK(22)) 120 121 #define jit_patch_set(sethi_pc, or_pc, dest) \ 122 (*(sethi_pc) &= ~_MASK(22), *(sethi_pc) |= _HI(dest), \ 123 *(or_pc) &= ~_MASK(13), *(or_pc) |= _LO(dest)) \ 124 125 #define jit_patch_movi(movi_pc, val) \ 126 jit_patch_set((movi_pc) - 2, (movi_pc) - 1, (val)) 127 128 #define jit_arg_c() (_jitl.nextarg_get++) 129 #define jit_arg_i() (_jitl.nextarg_get++) 130 #define jit_arg_l() (_jitl.nextarg_get++) 131 #define jit_arg_p() (_jitl.nextarg_get++) 132 #define jit_arg_s() (_jitl.nextarg_get++) 133 #define jit_arg_uc() (_jitl.nextarg_get++) 134 #define jit_arg_ui() (_jitl.nextarg_get++) 135 #define jit_arg_ul() (_jitl.nextarg_get++) 136 #define jit_arg_us() (_jitl.nextarg_get++) 137 #define jit_addi_i(d, rs, is) jit_chk_imm((is), ADDrir((rs), (is), (d)), ADDrrr((rs), JIT_BIG, (d))) 138 #define jit_addr_i(d, s1, s2) ADDrrr((s1), (s2), (d)) 139 #define jit_addci_i(d, rs, is) jit_chk_imm((is), ADDCCrir((rs), (is), (d)), ADDCCrrr((rs), JIT_BIG, (d))) 140 #define jit_addcr_i(d, s1, s2) ADDCCrrr((s1), (s2), (d)) 141 #define jit_addxi_i(d, rs, is) jit_chk_imm((is), ADDXCCrir((rs), (is), (d)), ADDXCCrrr((rs), JIT_BIG, (d))) 142 #define jit_addxr_i(d, s1, s2) ADDXCCrrr((s1), (s2), (d)) 143 #define jit_andi_i(d, rs, is) jit_chk_imm((is), ANDrir((rs), (is), (d)), ANDrrr((rs), JIT_BIG, (d))) 144 #define jit_andr_i(d, s1, s2) ANDrrr((s1), (s2), (d)) 145 #define jit_beqi_i(label, rs, is) jit_branchi((rs), (is), BEi((label)), NOP() ) 146 #define jit_beqr_i(label, s1, s2) jit_branchr((s1), (s2), BEi((label)), NOP() ) 147 #define jit_bgei_i(label, rs, is) jit_branchi((rs), (is), BGEi((label)), NOP() ) 148 #define jit_bgei_ui(label, rs, is) jit_branchi((rs), (is), BGEUi((label)), NOP() ) 149 #define jit_bger_i(label, s1, s2) jit_branchr((s1), (s2), BGEi((label)), NOP() ) 150 #define jit_bger_ui(label, s1, s2) jit_branchr((s1), (s2), BGEUi((label)), NOP() ) 151 #define jit_bgti_i(label, rs, is) jit_branchi((rs), (is), BGi((label)), NOP() ) 152 #define jit_bgti_ui(label, rs, is) jit_branchi((rs), (is), BGUi((label)), NOP() ) 153 #define jit_bgtr_i(label, s1, s2) jit_branchr((s1), (s2), BGi((label)), NOP() ) 154 #define jit_bgtr_ui(label, s1, s2) jit_branchr((s1), (s2), BGUi((label)), NOP() ) 155 #define jit_blei_i(label, rs, is) jit_branchi((rs), (is), BLEi((label)), NOP() ) 156 #define jit_blei_ui(label, rs, is) jit_branchi((rs), (is), BLEUi((label)), NOP() ) 157 #define jit_bler_i(label, s1, s2) jit_branchr((s1), (s2), BLEi((label)), NOP() ) 158 #define jit_bler_ui(label, s1, s2) jit_branchr((s1), (s2), BLEUi((label)), NOP() ) 159 #define jit_blti_i(label, rs, is) jit_branchi((rs), (is), BLi((label)), NOP() ) 160 #define jit_blti_ui(label, rs, is) jit_branchi((rs), (is), BLUi((label)), NOP() ) 161 #define jit_bltr_i(label, s1, s2) jit_branchr((s1), (s2), BLi((label)), NOP() ) 162 #define jit_bltr_ui(label, s1, s2) jit_branchr((s1), (s2), BLUi((label)), NOP() ) 163 #define jit_bnei_i(label, rs, is) jit_branchi((rs), (is), BNEi((label)), NOP() ) 164 #define jit_bner_i(label, s1, s2) jit_branchr((s1), (s2), BNEi((label)), NOP() ) 165 #define jit_bmsi_i(label, rs, is) (jit_chk_imm((is), BTSTir((is), (rs)), BTSTrr((rs), JIT_BIG)), BNEi((label)), NOP(), _jit.x.pc - 1) 166 #define jit_bmci_i(label, rs, is) (jit_chk_imm((is), BTSTir((is), (rs)), BTSTrr((rs), JIT_BIG)), BEi((label)), NOP(), _jit.x.pc - 1) 167 #define jit_bmsr_i(label, s1, s2) ( BTSTrr((s1), (s2)), BNEi((label)), NOP(), _jit.x.pc - 1) 168 #define jit_bmcr_i(label, s1, s2) ( BTSTrr((s1), (s2)), BEi((label)), NOP(), _jit.x.pc - 1) 169 #define jit_boaddi_i(label, rs, is) (jit_chk_imm((is), ADDCCrir((rs), (is), (rs)), ADDCCrrr((rs), JIT_BIG, (rs))), BVSi((label)), NOP(), _jit.x.pc - 1) 170 #define jit_bosubi_i(label, rs, is) (jit_chk_imm((is), SUBCCrir((rs), (is), (rs)), SUBCCrrr((rs), JIT_BIG, (rs))), BVSi((label)), NOP(), _jit.x.pc - 1) 171 #define jit_boaddr_i(label, s1, s2) ( ADDCCrrr((s1), (s2), (s1)), BVSi((label)), NOP(), _jit.x.pc - 1) 172 #define jit_bosubr_i(label, s1, s2) ( SUBCCrrr((s1), (s2), (s1)), BVSi((label)), NOP(), _jit.x.pc - 1) 173 #define jit_boaddi_ui(label, rs, is) (jit_chk_imm((is), ADDCCrir((rs), (is), (rs)), ADDCCrrr((rs), JIT_BIG, (rs))), BCSi((label)), NOP(), _jit.x.pc - 1) 174 #define jit_bosubi_ui(label, rs, is) (jit_chk_imm((is), SUBCCrir((rs), (is), (rs)), SUBCCrrr((rs), JIT_BIG, (rs))), BCSi((label)), NOP(), _jit.x.pc - 1) 175 #define jit_boaddr_ui(label, s1, s2) ( ADDCCrrr((s1), (s2), (s1)), BCSi((label)), NOP(), _jit.x.pc - 1) 176 #define jit_bosubr_ui(label, s1, s2) ( SUBCCrrr((s1), (s2), (s1)), BCSi((label)), NOP(), _jit.x.pc - 1) 177 #define jit_calli(label) (CALLi(label), NOP(), _jit.x.pc - 1) 178 #define jit_callr(reg) (CALLx((reg), 0), NOP()) 179 180 #define jit_divi_i(d, rs, is) (jit_prepare_y((rs), 0x12345678), SETir((is), JIT_BIG), SDIVrrr((rs), JIT_BIG, (d)) ) 181 #define jit_divi_ui(d, rs, is) (jit_clr_y((rs), 0x12345678), SETir((is), JIT_BIG), UDIVrrr((rs), JIT_BIG, (d)) ) 182 #define jit_divr_i(d, s1, s2) (jit_prepare_y((s1), 0), SDIVrrr((s1), (s2), (d))) 183 #define jit_divr_ui(d, s1, s2) (jit_clr_y((s1), 0), UDIVrrr((s1), (s2), (d))) 184 #define jit_eqi_i(d, rs, is) jit_chk_imm((is), \ 185 (SUBCCrir((rs), (is), (d)), ADDXCCrir((d), -1, JIT_BIG), SUBXrir(0,-1,(d))),\ 186 jit_eqr_i(d, rs, JIT_BIG)) 187 #define jit_eqr_i(d, s1, s2) (SUBCCrrr((s1), (s2), (d)), ADDXCCrir((d), -1, JIT_BIG), SUBXrir(0,-1,(d))) 188 #define jit_nei_i(d, rs, is) jit_chk_imm((is), \ 189 (SUBCCrir((rs), (is), (d)), ADDXCCrir((d), -1, JIT_BIG), ADDXrrr(0,0,(d))),\ 190 jit_ner_i(d, rs, JIT_BIG)) 191 #define jit_ner_i(d, s1, s2) (SUBCCrrr((s1), (s2), (d)), ADDXCCrir((d), -1, JIT_BIG), ADDXrrr(0,0,(d))) 192 #define jit_gei_i(d, rs, is) jit_booli ((d), (rs), (is), BGEi(_jit.x.pc + 3) ) 193 #define jit_gei_ui(d, rs, is) jit_booli ((d), (rs), (is), BGEUi(_jit.x.pc + 3)) 194 #define jit_ger_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BGEi(_jit.x.pc + 3) ) 195 #define jit_ger_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BGEUi(_jit.x.pc + 3)) 196 #define jit_gti_i(d, rs, is) jit_booli ((d), (rs), (is), BGi(_jit.x.pc + 3) ) 197 #define jit_gti_ui(d, rs, is) jit_booli ((d), (rs), (is), BGUi(_jit.x.pc + 3) ) 198 #define jit_gtr_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BGi(_jit.x.pc + 3) ) 199 #define jit_gtr_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BGUi(_jit.x.pc + 3) ) 200 #define jit_hmuli_i(d, rs, is) (jit_muli_i (JIT_BIG, (rs), (is)), RDir (_y, (d))) 201 #define jit_hmuli_ui(d, rs, is) (jit_muli_ui(JIT_BIG, (rs), (is)), RDir (_y, (d))) 202 #define jit_hmulr_i(d, s1, s2) (jit_mulr_i (JIT_BIG, (s1), (s2)), RDir (_y, (d))) 203 #define jit_hmulr_ui(d, s1, s2) (jit_mulr_ui(JIT_BIG, (s1), (s2)), RDir (_y, (d))) 204 #define jit_jmpi(label) (BA_Ai((label)), _jit.x.pc) 205 #define jit_jmpr(reg) (JMPx(JIT_RZERO, (reg)), NOP(), _jit.x.pc - 1) 206 #define jit_ldxi_c(d, rs, is) jit_chk_imm((is), LDSBmr((rs), (is), (d)), LDSBxr((rs), JIT_BIG, (d))) 207 #define jit_ldxi_i(d, rs, is) jit_chk_imm((is), LDSWmr((rs), (is), (d)), LDSWxr((rs), JIT_BIG, (d))) 208 #define jit_ldxi_s(d, rs, is) jit_chk_imm((is), LDSHmr((rs), (is), (d)), LDSHxr((rs), JIT_BIG, (d))) 209 #define jit_ldxi_uc(d, rs, is) jit_chk_imm((is), LDUBmr((rs), (is), (d)), LDUBxr((rs), JIT_BIG, (d))) 210 #define jit_ldxi_us(d, rs, is) jit_chk_imm((is), LDUHmr((rs), (is), (d)), LDUHxr((rs), JIT_BIG, (d))) 211 #define jit_ldxr_c(d, s1, s2) LDSBxr((s1), (s2), (d)) 212 #define jit_ldxr_i(d, s1, s2) LDSWxr((s1), (s2), (d)) 213 #define jit_ldxr_s(d, s1, s2) LDSHxr((s1), (s2), (d)) 214 #define jit_ldxr_uc(d, s1, s2) LDUBxr((s1), (s2), (d)) 215 #define jit_ldxr_us(d, s1, s2) LDUHxr((s1), (s2), (d)) 216 #define jit_lei_i(d, rs, is) jit_booli ((d), (rs), (is), BLEi(_jit.x.pc + 3) ) 217 #define jit_lei_ui(d, rs, is) jit_booli ((d), (rs), (is), BLEUi(_jit.x.pc + 3)) 218 #define jit_ler_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BLEi(_jit.x.pc + 3) ) 219 #define jit_ler_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BLEUi(_jit.x.pc + 3)) 220 #define jit_lshi_i(d, rs, is) SLLrir((rs), (is), (d)) 221 #define jit_lshr_i(d, r1, r2) SLLrrr((r1), (r2), (d)) 222 #define jit_lti_i(d, rs, is) jit_booli ((d), (rs), (is), BLi(_jit.x.pc + 3) ) 223 #define jit_lti_ui(d, rs, is) jit_booli ((d), (rs), (is), BLUi(_jit.x.pc + 3) ) 224 #define jit_ltr_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BLi(_jit.x.pc + 3) ) 225 #define jit_ltr_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BLUi(_jit.x.pc + 3) ) 226 #define jit_modi_i(d, rs, is) jit_modi(jit_divi_i, jit_muli_i, jit_divr_i, jit_mulr_i, (d), (rs), (is)) 227 #define jit_modi_ui(d, rs, is) jit_modi(jit_divi_ui, jit_muli_ui, jit_divr_ui, jit_mulr_ui, (d), (rs), (is)) 228 #define jit_modr_i(d, s1, s2) jit_modr(jit_divr_i, jit_mulr_i, (d), (s1), (s2)) 229 #define jit_modr_ui(d, s1, s2) jit_modr(jit_divr_ui, jit_mulr_ui, (d), (s1), (s2)) 230 #define jit_movi_i(d, is) SETir((is), (d)) 231 #define jit_movi_p(d, is) (SETir2(_HI((is)), _LO((is)), (d)), _jit.x.pc) 232 #define jit_movr_i(d, rs) MOVrr((rs), (d)) 233 #define jit_muli_i(d, rs, is) jit_chk_imm((is), SMULrir((rs), (is), (d)), SMULrrr((rs), JIT_BIG, (d))) 234 #define jit_muli_ui(d, rs, is) jit_chk_imm((is), UMULrir((rs), (is), (d)), UMULrrr((rs), JIT_BIG, (d))) 235 #define jit_mulr_i(d, s1, s2) SMULrrr((s1), (s2), (d)) 236 #define jit_mulr_ui(d, s1, s2) UMULrrr((s1), (s2), (d)) 237 #define jit_nop() NOP() 238 #define jit_ori_i(d, rs, is) jit_chk_imm((is), ORrir((rs), (is), (d)), ORrrr((rs), JIT_BIG, (d))) 239 #define jit_orr_i(d, s1, s2) ORrrr((s1), (s2), (d)) 240 #define jit_patch_at(delay_pc, pv) jit_patch_ (((delay_pc) - 1) , (pv)) 241 #define jit_popr_i(rs) (LDmr(JIT_SP, 0, (rs)), ADDrir(JIT_SP, 8, JIT_SP)) 242 #define jit_prepare_i(num) (_jitl.nextarg_put += (num)) 243 #define jit_prolog(numargs) (SAVErir(JIT_SP, -120, JIT_SP), _jitl.nextarg_get = _Ri(0)) 244 #define jit_pushr_i(rs) (STrm((rs), JIT_SP, -8), SUBrir(JIT_SP, 8, JIT_SP)) 245 #define jit_pusharg_i(rs) (--_jitl.nextarg_put, MOVrr((rs), _Ro(_jitl.nextarg_put))) 246 #define jit_ret() (RET(), RESTORE()) 247 #define jit_retval_i(rd) MOVrr(_Ro(0), (rd)) 248 #define jit_rshi_i(d, rs, is) SRArir((rs), (is), (d)) 249 #define jit_rshi_ui(d, rs, is) SRLrir((rs), (is), (d)) 250 #define jit_rshr_i(d, r1, r2) SRArrr((r1), (r2), (d)) 251 #define jit_rshr_ui(d, r1, r2) SRLrrr((r1), (r2), (d)) 252 #define jit_stxi_c(id, rd, rs) jit_chk_imm((id), STBrm((rs), (rd), (id)), STBrx((rs), (rd), JIT_BIG)) 253 #define jit_stxi_i(id, rd, rs) jit_chk_imm((id), STWrm((rs), (rd), (id)), STWrx((rs), (rd), JIT_BIG)) 254 #define jit_stxi_s(id, rd, rs) jit_chk_imm((id), STHrm((rs), (rd), (id)), STHrx((rs), (rd), JIT_BIG)) 255 #define jit_stxr_c(d1, d2, rs) STBrx((rs), (d1), (d2)) 256 #define jit_stxr_i(d1, d2, rs) STWrx((rs), (d1), (d2)) 257 #define jit_stxr_s(d1, d2, rs) STHrx((rs), (d1), (d2)) 258 #define jit_subr_i(d, s1, s2) SUBrrr((s1), (s2), (d)) 259 #define jit_subcr_i(d, s1, s2) SUBCCrrr((s1), (s2), (d)) 260 #define jit_subxi_i(d, rs, is) jit_chk_imm((is), SUBXCCrir((rs), (is), (d)), SUBXCCrrr((rs), JIT_BIG, (d))) 261 #define jit_subxr_i(d, s1, s2) SUBXCCrrr((s1), (s2), (d)) 262 #define jit_xori_i(d, rs, is) jit_chk_imm((is), XORrir((rs), (is), (d)), XORrrr((rs), JIT_BIG, (d))) 263 #define jit_xorr_i(d, s1, s2) XORrrr((s1), (s2), (d)) 264 265 #endif /* __lightning_core_h */ 266