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