bidirectional layout of vftbl/interfaces added
[cacao.git] / alpha / gen.c
1 /***************************** alpha/gen.c *************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         Contains the codegenerator for an Alpha processor.
8         This module generates Alpha machine code for a sequence of
9         pseudo commands (PCMDs).
10
11         Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
12                  Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
13
14         Last Change: 1997/10/22
15
16 *******************************************************************************/
17
18
19
20 /*******************************************************************************
21
22 Datatypes and Register Allocations:
23 ----------------------------------- 
24
25 On 64-bit-machines (like the Alpha) all operands are stored in the
26 registers in a 64-bit form, even when the correspondig JavaVM 
27 operands only need 32 bits.
28 This is done by a canonical representation:
29
30 32-bit integers are allways stored as sign-extended 64-bit values
31 (this approach is directly supported by the Alpha architecture and
32 is very easy to implement).
33
34 32-bit-floats are stored in a 64-bit doubleprecision register by
35 simply expanding the exponent and mantissa with zeroes.
36 (also supported by the architecture)
37
38
39 Stackframes:
40
41 The calling conventions and the layout of the stack is 
42 explained in detail in the documention file: calling.doc
43
44 *******************************************************************************/
45
46
47 /************************ Preallocated registers ******************************/
48
49 /* integer registers */
50   
51 #define REG_RESULT      0    /* to deliver method results                     */ 
52 #define REG_EXCEPTION   1    /* to throw an exception across method bounds    */
53
54 #define REG_RA                  26   /* return address                                */
55 #define REG_PV                  27   /* procedure vector, must be provided by caller  */
56 #define REG_METHODPTR   28   /* pointer to the place from where the procedure */
57                              /* vector has been fetched                       */
58 #define REG_ITMP1               25   /* temporary register                            */
59 #define REG_ITMP2               28   /* temporary register                            */
60 #define REG_ITMP3               29   /* temporary register                            */
61
62 #define REG_SP                  30   /* stack pointer                                 */
63 #define REG_ZERO                31   /* allways zero                                  */
64
65 /* floating point registers */
66
67 #define REG_FRESULT     0    /* to deliver floating point method results      */ 
68 #define REG_FTMP1       28   /* temporary floating point register             */
69 #define REG_FTMP2       29   /* temporary floating point register             */
70 #define REG_FTMP3       30   /* temporary floating point register             */
71
72
73 /******************** register descripton - array *****************************/
74
75 /* #define REG_RES   0         reserved register for OS or code generator */
76 /* #define REG_RET   1         return value register */
77 /* #define REG_EXC   2         exception value register */
78 /* #define REG_SAV   3         (callee) saved register */
79 /* #define REG_TMP   4         scratch temporary register (caller saved) */
80 /* #define REG_ARG   5         argument register (caller saved) */
81
82 /* #define REG_END   -1        last entry in tables */
83  
84 int regdescint[] = {
85         REG_RET, REG_EXC, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, 
86         REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, 
87         REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
88         REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
89         REG_END };
90
91 #define INT_SAV_FST      9   /* first int callee saved register               */
92 #define INT_SAV_CNT      7   /* number of int callee saved registers          */
93 #define INT_ARG_FST     16   /* first int callee saved register               */
94 #define INT_ARG_CNT      6   /* number of int callee saved registers          */
95
96 /* for use of reserved registers, see comment above */
97         
98 int regdescfloat[] = {
99         REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
100         REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, 
101         REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
102         REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
103         REG_END };
104
105 #define FLT_SAV_FST      2   /* first int callee saved register               */
106 #define FLT_SAV_CNT      8   /* number of int callee saved registers          */
107 #define FLT_ARG_FST     16   /* first int callee saved register               */
108 #define FLT_ARG_CNT      6   /* number of int callee saved registers          */
109
110 /* for use of reserved registers, see comment above */
111
112
113 /*** parameter allocation mode ***/
114
115 int reg_parammode = PARAMMODE_NUMBERED;  
116
117    /* parameter-registers will be allocated by assigning the
118       1. parameter:   int/float-reg 16
119       2. parameter:   int/float-reg 17  
120       3. parameter:   int/float-reg 18 ....
121    */
122
123
124 /************************** stackframe-infos **********************************/
125
126 int localvars_base;  /* offset in stackframe for the local variables          */
127 int savedregs_base;  /* offset in stackframe for the save area                */
128 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
129
130 /* -> see file 'calling.doc' */
131
132
133 /******************** macros to create code ***********************************/
134
135 /* 3-address-operations: M_OP3
136       op ..... opcode
137       fu ..... function-number
138       a  ..... register number source 1
139       b  ..... register number or constant integer source 2
140       c  ..... register number destination
141       const .. switch to use b as constant integer 
142                  (0 means: use b as register number)
143                  (1 means: use b as constant 8-bit-integer)
144 */      
145 #define M_OP3(op,fu,a,b,c,const) \
146         mcode_adds4 ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
147         ((const)<<12)|((fu)<<5)|((c)) )
148
149 /* 3-address-floating-point-operation: M_FOP3 
150      op .... opcode
151      fu .... function-number
152      a,b ... source floating-point registers
153      c ..... destination register
154 */ 
155 #define M_FOP3(op,fu,a,b,c) \
156         mcode_adds4 ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
157
158 /* branch instructions: M_BRA 
159       op ..... opcode
160       a ...... register to be tested
161       disp ... relative address to be jumped to (divided by 4)
162 */
163 #define M_BRA(op,a,disp) \
164         mcode_adds4 ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
165
166
167 /* memory operations: M_MEM
168       op ..... opcode
169       a ...... source/target register for memory access
170       b ...... base register
171       disp ... displacement (16 bit signed) to be added to b
172 */ 
173 #define M_MEM(op,a,b,disp) \
174         mcode_adds4 ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
175
176
177 /***** macros for all used commands (see an Alpha-manual for description) *****/ 
178
179 #define M_LDA(a,b,disp)         M_MEM (0x08,a,b,disp)           /* low const  */
180 #define M_LDAH(a,b,disp)        M_MEM (0x09,a,b,disp)           /* high const */
181 #define M_BLDU(a,b,disp)        M_MEM (0x0a,a,b,disp)           /*  8 load    */
182 #define M_SLDU(a,b,disp)        M_MEM (0x0c,a,b,disp)           /* 16 load    */
183 #define M_ILD(a,b,disp)         M_MEM (0x28,a,b,disp)           /* 32 load    */
184 #define M_LLD(a,b,disp)         M_MEM (0x29,a,b,disp)           /* 64 load    */
185 #define M_BST(a,b,disp)         M_MEM (0x0e,a,b,disp)           /*  8 store   */
186 #define M_SST(a,b,disp)         M_MEM (0x0d,a,b,disp)           /* 16 store   */
187 #define M_IST(a,b,disp)         M_MEM (0x2c,a,b,disp)           /* 32 store   */
188 #define M_LST(a,b,disp)         M_MEM (0x2d,a,b,disp)           /* 64 store   */
189
190 #define M_BSEXT(b,c)            M_OP3 (0x1c,0x0,REG_ZERO,b,c,0) /*  8 signext */
191 #define M_SSEXT(b,c)            M_OP3 (0x1c,0x1,REG_ZERO,b,c,0) /* 16 signext */
192
193 #define M_BR(disp)              M_BRA (0x30,REG_ZERO,disp)      /* branch     */
194 #define M_BSR(ra,disp)          M_BRA (0x34,ra,disp)            /* branch sbr */
195 #define M_BEQZ(a,disp)          M_BRA (0x39,a,disp)             /* br a == 0  */
196 #define M_BLTZ(a,disp)          M_BRA (0x3a,a,disp)             /* br a <  0  */
197 #define M_BLEZ(a,disp)          M_BRA (0x3b,a,disp)             /* br a <= 0  */
198 #define M_BNEZ(a,disp)          M_BRA (0x3d,a,disp)             /* br a != 0  */
199 #define M_BGEZ(a,disp)          M_BRA (0x3e,a,disp)             /* br a >= 0  */
200 #define M_BGTZ(a,disp)          M_BRA (0x3f,a,disp)             /* br a >  0  */
201
202 #define M_JMP(a,b)              M_MEM (0x1a,a,b,0x0000)         /* jump       */
203 #define M_JSR(a,b)              M_MEM (0x1a,a,b,0x4000)         /* call sbr   */
204 #define M_RET(a,b)              M_MEM (0x1a,a,b,0x8000)         /* return     */
205
206 #define M_IADD(a,b,c,const)     M_OP3 (0x10,0x0,  a,b,c,const)  /* 32 add     */
207 #define M_LADD(a,b,c,const)     M_OP3 (0x10,0x20, a,b,c,const)  /* 64 add     */
208 #define M_ISUB(a,b,c,const)     M_OP3 (0x10,0x09, a,b,c,const)  /* 32 sub     */
209 #define M_LSUB(a,b,c,const)     M_OP3 (0x10,0x29, a,b,c,const)  /* 64 sub     */
210 #define M_IMUL(a,b,c,const)     M_OP3 (0x13,0x00, a,b,c,const)  /* 32 mul     */
211 #define M_LMUL(a,b,c,const)     M_OP3 (0x13,0x20, a,b,c,const)  /* 64 mul     */
212
213 #define M_CMPEQ(a,b,c,const)    M_OP3 (0x10,0x2d, a,b,c,const)  /* c = a == b */
214 #define M_CMPLT(a,b,c,const)    M_OP3 (0x10,0x4d, a,b,c,const)  /* c = a <  b */
215 #define M_CMPLE(a,b,c,const)    M_OP3 (0x10,0x6d, a,b,c,const)  /* c = a <= b */
216
217 #define M_CMPULE(a,b,c,const)   M_OP3 (0x10,0x3d, a,b,c,const)  /* c = a <= b */
218
219 #define M_AND(a,b,c,const)      M_OP3 (0x11,0x00, a,b,c,const)  /* c = a &  b */
220 #define M_OR(a,b,c,const)       M_OP3 (0x11,0x20, a,b,c,const)  /* c = a |  b */
221 #define M_XOR(a,b,c,const)      M_OP3 (0x11,0x40, a,b,c,const)  /* c = a ^  b */
222
223 #define M_SLL(a,b,c,const)      M_OP3 (0x12,0x39, a,b,c,const)  /* c = a << b */
224 #define M_SRA(a,b,c,const)      M_OP3 (0x12,0x3c, a,b,c,const)  /* c = a >> b */
225 #define M_SRL(a,b,c,const)      M_OP3 (0x12,0x34, a,b,c,const)  /* c = a >>>b */
226
227 #define M_FLD(a,b,disp)         M_MEM (0x22,a,b,disp)           /* load flt   */
228 #define M_DLD(a,b,disp)         M_MEM (0x23,a,b,disp)           /* load dbl   */
229 #define M_FST(a,b,disp)         M_MEM (0x26,a,b,disp)           /* store flt  */
230 #define M_DST(a,b,disp)         M_MEM (0x27,a,b,disp)           /* store dbl  */
231
232 #define M_FADD(a,b,c)           M_FOP3 (0x16, 0x080, a,b,c)     /* flt add    */
233 #define M_DADD(a,b,c)           M_FOP3 (0x16, 0x0a0, a,b,c)     /* dbl add    */
234 #define M_FSUB(a,b,c)           M_FOP3 (0x16, 0x081, a,b,c)     /* flt sub    */
235 #define M_DSUB(a,b,c)           M_FOP3 (0x16, 0x0a1, a,b,c)     /* dbl sub    */
236 #define M_FMUL(a,b,c)           M_FOP3 (0x16, 0x082, a,b,c)     /* flt mul    */
237 #define M_DMUL(a,b,c)           M_FOP3 (0x16, 0x0a2, a,b,c)     /* dbl mul    */
238 #define M_FDIV(a,b,c)           M_FOP3 (0x16, 0x083, a,b,c)     /* flt div    */
239 #define M_DDIV(a,b,c)           M_FOP3 (0x16, 0x0a3, a,b,c)     /* dbl div    */
240
241 #define M_CVTLF(a,b,c)          M_FOP3 (0x16, 0x0bc, a,b,c)     /* long2flt   */
242 #define M_CVTLD(a,b,c)          M_FOP3 (0x16, 0x0be, a,b,c)     /* long2dbl   */
243 #define M_CVTDL(a,b,c)          M_FOP3 (0x16, 0x0af, a,b,c)     /* dbl2long   */
244 #define M_CVTDL_C(a,b,c)        M_FOP3 (0x16, 0x02f, a,b,c)     /* dbl2long   */
245
246 #define M_FCMPEQ(a,b,c)         M_FOP3 (0x16, 0x0a5, a,b,c)     /* c = a==b   */
247 #define M_FCMPLT(a,b,c)         M_FOP3 (0x16, 0x0a6, a,b,c)     /* c = a<b    */
248
249 #define M_FMOV(fa,fb)           M_FOP3 (0x17, 0x020, fa,fa,fb)  /* b = a      */
250 #define M_FMOVN(fa,fb)          M_FOP3 (0x17, 0x021, fa,fa,fb)  /* b = -a     */
251
252 #define M_FBEQZ(fa,disp)        M_BRA (0x31,fa,disp)            /* br a == 0.0*/
253
254 /****** macros for special commands (see an Alpha-manual for description) *****/ 
255
256 #define M_S4ADDL(a,b,c,const)   M_OP3 (0x10,0x02, a,b,c,const) /* c = a*4 + b */
257 #define M_S4ADDQ(a,b,c,const)   M_OP3 (0x10,0x22, a,b,c,const) /* c = a*4 + b */
258 #define M_S4SUBL(a,b,c,const)   M_OP3 (0x10,0x0b, a,b,c,const) /* c = a*4 - b */
259 #define M_S4SUBQ(a,b,c,const)   M_OP3 (0x10,0x2b, a,b,c,const) /* c = a*4 - b */
260 #define M_S8ADDL(a,b,c,const)   M_OP3 (0x10,0x12, a,b,c,const) /* c = a*8 + b */
261 #define M_S8ADDQ(a,b,c,const)   M_OP3 (0x10,0x32, a,b,c,const) /* c = a*8 + b */
262 #define M_S8SUBL(a,b,c,const)   M_OP3 (0x10,0x1b, a,b,c,const) /* c = a*8 - b */
263 #define M_S8SUBQ(a,b,c,const)   M_OP3 (0x10,0x3b, a,b,c,const) /* c = a*8 - b */
264
265 #define M_LLD_U(a,b,disp)       M_MEM (0x0b,a,b,disp)          /* unalign ld  */
266 #define M_LST_U(a,b,disp)       M_MEM (0x0f,a,b,disp)          /* unalign st  */
267
268 #define M_ZAP(a,b,c,const)      M_OP3 (0x12,0x30, a,b,c,const)
269 #define M_ZAPNOT(a,b,c,const)   M_OP3 (0x12,0x31, a,b,c,const)
270 #define M_EXTBL(a,b,c,const)    M_OP3 (0x12,0x06, a,b,c,const)
271 #define M_EXTWL(a,b,c,const)    M_OP3 (0x12,0x16, a,b,c,const)
272 #define M_EXTLL(a,b,c,const)    M_OP3 (0x12,0x26, a,b,c,const)
273 #define M_EXTQL(a,b,c,const)    M_OP3 (0x12,0x36, a,b,c,const)
274 #define M_EXTWH(a,b,c,const)    M_OP3 (0x12,0x5a, a,b,c,const)
275 #define M_EXTLH(a,b,c,const)    M_OP3 (0x12,0x6a, a,b,c,const)
276 #define M_EXTQH(a,b,c,const)    M_OP3 (0x12,0x7a, a,b,c,const)
277 #define M_INSBL(a,b,c,const)    M_OP3 (0x12,0x0b, a,b,c,const)
278 #define M_INSWL(a,b,c,const)    M_OP3 (0x12,0x1b, a,b,c,const)
279 #define M_INSLL(a,b,c,const)    M_OP3 (0x12,0x2b, a,b,c,const)
280 #define M_INSQL(a,b,c,const)    M_OP3 (0x12,0x3b, a,b,c,const)
281 #define M_INSWH(a,b,c,const)    M_OP3 (0x12,0x57, a,b,c,const)
282 #define M_INSLH(a,b,c,const)    M_OP3 (0x12,0x67, a,b,c,const)
283 #define M_INSQH(a,b,c,const)    M_OP3 (0x12,0x77, a,b,c,const)
284 #define M_MSKBL(a,b,c,const)    M_OP3 (0x12,0x02, a,b,c,const)
285 #define M_MSKWL(a,b,c,const)    M_OP3 (0x12,0x12, a,b,c,const)
286 #define M_MSKLL(a,b,c,const)    M_OP3 (0x12,0x22, a,b,c,const)
287 #define M_MSKQL(a,b,c,const)    M_OP3 (0x12,0x32, a,b,c,const)
288 #define M_MSKWH(a,b,c,const)    M_OP3 (0x12,0x52, a,b,c,const)
289 #define M_MSKLH(a,b,c,const)    M_OP3 (0x12,0x62, a,b,c,const)
290 #define M_MSKQH(a,b,c,const)    M_OP3 (0x12,0x72, a,b,c,const)
291
292
293 /****** macros for unused commands (see an Alpha-manual for description) ******/ 
294
295 #define M_ANDNOT(a,b,c,const)   M_OP3 (0x11,0x08, a,b,c,const) /* c = a &~ b  */
296 #define M_ORNOT(a,b,c,const)    M_OP3 (0x11,0x28, a,b,c,const) /* c = a |~ b  */
297 #define M_XORNOT(a,b,c,const)   M_OP3 (0x11,0x48, a,b,c,const) /* c = a ^~ b  */
298
299 #define M_CMOVEQ(a,b,c,const)   M_OP3 (0x11,0x24, a,b,c,const) /* a==0 ? c=b  */
300 #define M_CMOVNE(a,b,c,const)   M_OP3 (0x11,0x26, a,b,c,const) /* a!=0 ? c=b  */
301 #define M_CMOVLT(a,b,c,const)   M_OP3 (0x11,0x44, a,b,c,const) /* a< 0 ? c=b  */
302 #define M_CMOVGE(a,b,c,const)   M_OP3 (0x11,0x46, a,b,c,const) /* a>=0 ? c=b  */
303 #define M_CMOVLE(a,b,c,const)   M_OP3 (0x11,0x64, a,b,c,const) /* a<=0 ? c=b  */
304 #define M_CMOVGT(a,b,c,const)   M_OP3 (0x11,0x66, a,b,c,const) /* a> 0 ? c=b  */
305
306 #define M_CMPULT(a,b,c,const)   M_OP3 (0x10,0x1d, a,b,c,const)
307 #define M_CMPBGE(a,b,c,const)   M_OP3 (0x10,0x0f, a,b,c,const)
308
309 #define M_FCMPUN(a,b,c)         M_FOP3 (0x16, 0x0a4, a,b,c)    /* unordered   */
310 #define M_FCMPLE(a,b,c)         M_FOP3 (0x16, 0x0a7, a,b,c)    /* c = a<=b    */
311
312 #define M_FBNEZ(fa,disp)        M_BRA (0x35,fa,disp)
313 #define M_FBLEZ(fa,disp)        M_BRA (0x33,fa,disp)
314
315 #define M_JMP_CO(a,b)           M_MEM (0x1a,a,b,0xc000)        /* call cosub  */
316
317
318 /******************** system independent macros *******************************/
319  
320
321
322 /************** additional functions to generate code *************************/
323
324
325 /* M_INTMOVE:
326      generates an integer-move from register a to b.
327      if a and b are the same int-register, no code will be generated.
328 */ 
329
330 static void M_INTMOVE(int a, int b)
331 {
332         if (a == b) return;
333         M_OR (a,a,b, 0);
334 }
335
336
337 /* M_FLTMOVE:
338     generates a floating-point-move from register a to b.
339     if a and b are the same float-register, no code will be generated
340 */ 
341
342 static void M_FLTMOVE(int a, int b)
343 {
344         if (a == b) return;
345         M_FMOV (a, b);
346 }
347
348
349 /* var_to_reg_xxx:
350     this function generates code to fetch data from a pseudo-register
351     into a real register. 
352     If the pseudo-register has actually been assigned to a real 
353     register, no code will be emitted, since following operations
354     can use this register directly.
355     
356     v: pseudoregister to be fetched from
357     tempregnum: temporary register to be used if v is actually spilled to ram
358
359     return: the register number, where the operand can be found after 
360             fetching (this wil be either tempregnum or the register
361             number allready given to v)
362 */
363
364 static int var_to_reg_int (varid v, int tempregnum)
365 {
366         reginfo *ri = v->reg;
367
368         if (!(ri->typeflags & REG_INMEMORY))
369                 return ri->num;
370 #ifdef STATISTICS
371         count_spills++;
372 #endif
373         M_LLD (tempregnum, REG_SP, 8 * (localvars_base + ri->num) );
374         return tempregnum;
375 }
376
377
378 static int var_to_reg_flt (varid v, int tempregnum)
379 {
380         reginfo *ri = v->reg;
381
382
383         if (!(ri->typeflags & REG_INMEMORY))
384                 return ri->num;
385 #ifdef STATISTICS
386         count_spills++;
387 #endif
388         M_DLD (tempregnum, REG_SP, 8 * (localvars_base + ri->num) );
389         return tempregnum;
390 }
391
392
393 /* reg_of_var:
394      This function determines a register, to which the result of an
395      operation should go, when it is ultimatively intended to store the result
396      in pseudoregister v.
397      If v is assigned to an actual register, this register will be
398      returned.
399      Otherwise (when v is spilled) this function returns tempregnum.
400 */        
401
402 static int reg_of_var(varid v, int tempregnum)
403 {
404         if (!(v->reg->typeflags & REG_INMEMORY))
405                 return v->reg->num;
406         return tempregnum;
407 }
408
409
410 /* store_reg_to_var_xxx:
411     This function generates the code to store the result of an operation
412     back into a spilled pseudo-variable.
413     If the pseudo-variable has not been spilled in the first place, this 
414     function will generate nothing.
415     
416     v ............ Pseudovariable
417     tempregnum ... Number of the temporary registers as returned by
418                    reg_of_var.
419 */      
420
421 static void store_reg_to_var_int (varid v, int tempregnum)
422 {
423         reginfo *ri = v->reg;
424
425         if (!(ri->typeflags & REG_INMEMORY))
426                 return;
427 #ifdef STATISTICS
428         count_spills++;
429 #endif
430         M_LST (tempregnum, REG_SP, 8 * (localvars_base + ri->num) );
431 }
432
433 static void store_reg_to_var_flt (varid v, int tempregnum)
434 {
435         reginfo *ri = v->reg;
436
437         if (!(ri->typeflags & REG_INMEMORY))
438                 return;
439 #ifdef STATISTICS
440         count_spills++;
441 #endif
442         M_DST (tempregnum, REG_SP, 8 * (localvars_base + ri->num) );
443 }
444
445
446 /***************** functions to process the pseudo commands *******************/
447
448 /* gen_method:
449     function to generate method-call
450 */
451
452 static void gen_method (pcmd *c)
453 {
454         int p, pa, r;
455         s4  a;
456         reginfo *ri;
457         classinfo *ci;
458         
459         for (p = 0; p < c->u.method.paramnum; p++) {
460                 ri = c->u.method.params[p]->reg;
461
462                 if (p < INT_ARG_CNT) {            /* arguments that go into registers */
463                         if (IS_INT_LNG_REG(ri->typeflags)) {
464                                 if (!(ri->typeflags & REG_INMEMORY))
465                                         M_INTMOVE(ri->num, INT_ARG_FST+p);
466                                 else
467                                         M_LLD(INT_ARG_FST+p, REG_SP, 8*(localvars_base + ri->num));
468                                 }
469                         else {
470                                 if (!(ri->typeflags & REG_INMEMORY))
471                                         M_FLTMOVE (ri->num, FLT_ARG_FST+p);
472                                 else
473                                         M_DLD(FLT_ARG_FST+p, REG_SP, 8*(localvars_base + ri->num));
474                                 }
475                         }
476                 else {                             /* arguments that go into memory   */
477                         pa = p - INT_ARG_CNT;
478                         if (pa >= arguments_num)
479                                 panic ("invalid stackframe structure");
480                         
481                         if (IS_INT_LNG_REG(ri->typeflags)) {
482                                 r = var_to_reg_int (c->u.method.params[p], REG_ITMP1);
483                                 M_LST(r, REG_SP, 8 * (0 + pa));
484                                 }
485                         else {
486                                 r = var_to_reg_flt (c->u.method.params[p], REG_FTMP1);
487                                 M_DST (r, REG_SP, 8 * (0 + pa));
488                                 }
489                         }
490                 }  /* end of for */
491
492         switch (c->opcode) {
493                 case CMD_BUILTIN:
494                         a = dseg_addaddress ( (void*) (c->u.method.builtin) );
495
496                         M_LLD (REG_PV, REG_PV, a);        /* Pointer to built-in-function */
497                         goto makeactualcall;
498
499                 case CMD_INVOKESTATIC:
500                 case CMD_INVOKESPECIAL:
501                         a = dseg_addaddress ( c->u.method.method->stubroutine );
502
503                         M_LLD (REG_PV, REG_PV, a );              /* Method-Pointer in r27 */
504
505                         goto makeactualcall;
506
507                 case CMD_INVOKEVIRTUAL:
508
509                         M_LLD (REG_METHODPTR, 16, OFFSET(java_objectheader, vftbl));
510                         M_LLD (REG_PV, REG_METHODPTR,
511                            OFFSET(vftbl,table[0]) + 
512                            sizeof(methodptr) * c->u.method.method->vftblindex );
513
514                         goto makeactualcall;
515
516                 case CMD_INVOKEINTERFACE:
517                         ci = c->u.method.method->class;
518                         
519                         M_LLD (REG_METHODPTR, 16, OFFSET(java_objectheader, vftbl));    
520                         M_LLD (REG_METHODPTR, REG_METHODPTR, OFFSET(vftbl, interfacetable[0]) -
521                                sizeof(methodptr*) * ci->index);
522                         M_LLD (REG_PV, REG_METHODPTR, sizeof(methodptr) * (c->u.method.method - ci->methods) );
523
524                         goto makeactualcall;
525
526                 default:
527                         sprintf (logtext, "Unkown PCMD-Command: %d", c->opcode);
528                         error ();
529                 }
530
531
532 makeactualcall:
533
534
535         M_JSR (REG_RA, REG_PV);
536         if (mcodelen<=32768) M_LDA (REG_PV, REG_RA, -mcodelen);
537         else {
538                 s4 ml=-mcodelen, mh=0;
539                 while (ml<-32768) { ml+=65536; mh--; }
540                 M_LDA (REG_PV, REG_RA, ml );
541                 M_LDAH (REG_PV, REG_PV, mh );
542         }
543         
544         if ( c->dest ) {
545                 ri = c->dest->reg;
546
547                 if (IS_INT_LNG_REG(ri->typeflags)) {
548                         if (!(ri->typeflags & REG_INMEMORY))
549                                 M_INTMOVE (REG_RESULT, ri->num);
550                         else  M_LST (REG_RESULT, REG_SP, 8 * (localvars_base + ri->num) );
551                         }
552                 else {
553                         if (!(ri->typeflags & REG_INMEMORY))
554                                 M_FLTMOVE (REG_RESULT, ri->num);
555                         else  M_DST (REG_RESULT, REG_SP, 8 * (localvars_base + ri->num) );
556                         }
557                 }
558
559         if (c->u.method.exceptionvar) {
560                 ri = c->u.method.exceptionvar->reg;
561                 if (!(ri->typeflags & REG_INMEMORY))
562                         M_INTMOVE (REG_EXCEPTION, ri->num);     
563                 else M_LST (REG_EXCEPTION, REG_SP, 8 *(localvars_base + ri->num) );
564                 }
565 }
566
567
568 /************************ function block_genmcode ******************************
569
570         generates machine code for a complete basic block
571
572 *******************************************************************************/
573
574
575 static void block_genmcode(basicblock *b)
576 {
577         int  s1, s2, s3, d;
578         s4   a;
579         pcmd *c;
580                         
581         mcode_blockstart (b);
582
583         for(c = list_first(&(b->pcmdlist));
584             c != NULL;
585             c = list_next(&(b->pcmdlist), c))
586
587         switch (c->opcode) {
588
589                 case CMD_TRACEBUILT:
590                         M_LDA (REG_SP, REG_SP, -8);
591                         a = dseg_addaddress (c->u.a.value);
592                         M_LLD(REG_ITMP1, REG_PV, a);
593                         M_LST(REG_ITMP1, REG_SP, 0);
594                         a = dseg_addaddress ((void*) (builtin_trace_args));
595                         M_LLD(REG_PV, REG_PV, a);
596                         M_JSR (REG_RA, REG_PV);
597                         if (mcodelen<=32768) M_LDA (REG_PV, REG_RA, -mcodelen);
598                         else {
599                                 s4 ml=-mcodelen, mh=0;
600                                 while (ml<-32768) { ml+=65536; mh--; }
601                                 M_LDA (REG_PV, REG_RA, ml );
602                                 M_LDAH (REG_PV, REG_PV, mh );
603                                 }
604                         M_LDA (REG_SP, REG_SP, 8);
605                         b -> mpc = mcodelen;
606                         break;
607
608
609                 /*********************** constant operations **************************/
610
611                 case CMD_LOADCONST_I:
612                         d = reg_of_var(c->dest, REG_ITMP1);
613                         if ( (c->u.i.value >= -32768) && (c->u.i.value <= 32767) ) {
614                                 M_LDA (d, REG_ZERO, c->u.i.value);
615                                 } 
616                         else {
617                                 a = dseg_adds4 (c->u.i.value);
618                                 M_ILD (d, REG_PV, a);
619                                 }
620                         store_reg_to_var_int(c->dest, d);
621                         break;
622
623                 case CMD_LOADCONST_L:
624                         d = reg_of_var(c->dest, REG_ITMP1);
625 #if U8_AVAILABLE
626                         if ((c->u.l.value >= -32768) && (c->u.l.value <= 32767) ) {
627                                 M_LDA (d, REG_ZERO, c->u.l.value);
628                                 } 
629                         else {
630                                 a = dseg_adds8 (c->u.l.value);
631                                 M_LLD (d, REG_PV, a);
632                                 }
633 #else
634                         a = dseg_adds8 (c->u.l.value);
635                         M_LLD (d, REG_PV, a);
636 #endif
637                         store_reg_to_var_int(c->dest, d);
638                         break;
639
640                 case CMD_LOADCONST_F:
641                         d = reg_of_var (c->dest, REG_FTMP1);
642                         a = dseg_addfloat (c->u.f.value);
643                         M_FLD (d, REG_PV, a);
644                         store_reg_to_var_flt (c->dest, d);
645                         break;
646                         
647                 case CMD_LOADCONST_D:
648                         d = reg_of_var (c->dest, REG_FTMP1);
649                         a = dseg_adddouble (c->u.d.value);
650                         M_DLD (d, REG_PV, a);
651                         store_reg_to_var_flt (c->dest, d);
652                         break;
653
654
655                 case CMD_LOADCONST_A:
656                         d = reg_of_var(c->dest, REG_ITMP1);
657                         if (c->u.a.value) {
658                                 a = dseg_addaddress (c->u.a.value);
659                                 M_LLD (d, REG_PV, a);
660                                 }
661                         else {
662                                 M_INTMOVE (REG_ZERO, d);
663                                 }
664                         store_reg_to_var_int(c->dest, d);
665                         break;
666
667                 /************************* move operation *****************************/
668
669                 case CMD_MOVE:
670                         if (IS_INT_LNG_REG(c->source1->reg->typeflags)) {
671                                 d = reg_of_var(c->dest, REG_ITMP1);
672                                 s1 = var_to_reg_int(c->source1, d);
673                                 M_INTMOVE(s1,d);
674                                 store_reg_to_var_int(c->dest, d);
675                                 }
676                         else {
677                                 d = reg_of_var(c->dest, REG_FTMP1);
678                                 s1 = var_to_reg_flt(c->source1, d);
679                                 M_FLTMOVE(s1,d);
680                                 store_reg_to_var_flt(c->dest, d);
681                                 }
682                         break;
683
684
685                 /********************* integer operations *****************************/
686
687                 case CMD_IINC:
688                         s1 = var_to_reg_int(c->source1, REG_ITMP1); 
689                         d = reg_of_var(c->dest, REG_ITMP3);
690                         if ((c->u.i.value >= 0) && (c->u.i.value <= 256)) {
691                                 M_IADD (s1, c->u.i.value, d, 1);
692                                 }
693                         else if ((c->u.i.value >= -256) && (c->u.i.value < 0)) {
694                                 M_ISUB (s1, (-c->u.i.value), d, 1);
695                                 }
696                         else {
697                                 M_LDA  (d, s1, c->u.i.value);
698                                 M_IADD (d, REG_ZERO, d, 0);
699                                 }
700                         store_reg_to_var_int(c->dest, d);
701                         break;
702
703                 case CMD_INEG:
704                         s1 = var_to_reg_int(c->source1, REG_ITMP1); 
705                         d = reg_of_var(c->dest, REG_ITMP3);
706                         M_ISUB (REG_ZERO, s1, d, 0);
707                         store_reg_to_var_int(c->dest, d);
708                         break;
709
710                 case CMD_LNEG:
711                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
712                         d = reg_of_var(c->dest, REG_ITMP3);
713                         M_LSUB (REG_ZERO, s1, d, 0);
714                         store_reg_to_var_int(c->dest, d);
715                         break;
716
717                 case CMD_I2L:
718                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
719                         d = reg_of_var(c->dest, REG_ITMP3);
720                         M_INTMOVE (s1, d);
721                         store_reg_to_var_int(c->dest, d);
722                         break;
723
724                 case CMD_L2I:
725                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
726                         d = reg_of_var(c->dest, REG_ITMP3);
727                         M_IADD (s1, REG_ZERO, d , 0);
728                         store_reg_to_var_int(c->dest, d);
729                         break;
730
731                 case CMD_INT2BYTE:
732                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
733                         d = reg_of_var(c->dest, REG_ITMP3);
734                         if (has_ext_instr_set) {
735                                 M_BSEXT  (s1, d);
736                                 }
737                         else {
738                                 M_SLL (s1,56, d, 1);
739                                 M_SRA ( d,56, d, 1);
740                                 }
741                         store_reg_to_var_int(c->dest, d);
742                         break;
743
744                 case CMD_INT2CHAR:
745                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
746                         d = reg_of_var(c->dest, REG_ITMP3);
747             M_ZAPNOT (s1, 0x03, d, 1);
748                         store_reg_to_var_int(c->dest, d);
749                         break;
750
751                 case CMD_INT2SHORT:
752                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
753                         d = reg_of_var(c->dest, REG_ITMP3);
754                         if (has_ext_instr_set) {
755                                 M_SSEXT  (s1, d);
756                                 }
757                         else {
758                                 M_SLL ( s1, 48, d, 1);
759                                 M_SRA (  d, 48, d, 1);
760                                 }
761                         store_reg_to_var_int(c->dest, d);
762                         break;
763
764                 case CMD_IADD:
765                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
766                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
767                         d = reg_of_var(c->dest, REG_ITMP3);
768                         M_IADD (s1, s2, d,  0);
769                         store_reg_to_var_int(c->dest, d);
770                         break;
771                 case CMD_LADD:
772                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
773                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
774                         d = reg_of_var(c->dest, REG_ITMP3);
775                         M_LADD (s1, s2, d,  0);
776                         store_reg_to_var_int(c->dest, d);
777                         break;
778
779                 case CMD_ISUB:
780                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
781                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
782                         d = reg_of_var(c->dest, REG_ITMP3);
783                         M_ISUB (s1, s2, d, 0);
784                         store_reg_to_var_int(c->dest, d);
785                         break;
786                 case CMD_LSUB:
787                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
788                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
789                         d = reg_of_var(c->dest, REG_ITMP3);
790                         M_LSUB (s1, s2, d, 0);
791                         store_reg_to_var_int(c->dest, d);
792                         break;
793
794                 case CMD_IMUL:
795                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
796                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
797                         d = reg_of_var(c->dest, REG_ITMP3);
798                         M_IMUL (s1, s2, d, 0);
799                         store_reg_to_var_int(c->dest, d);
800                         break;
801                 case CMD_LMUL:
802                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
803                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
804                         d = reg_of_var(c->dest, REG_ITMP3);
805                         M_LMUL (s1, s2, d, 0);
806                         store_reg_to_var_int(c->dest, d);
807                         break;
808
809                     
810                 case CMD_ISHL:
811                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
812                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
813                         d = reg_of_var(c->dest, REG_ITMP3);
814                         M_AND (s2, 0x1f, REG_ITMP3, 1);
815                         M_SLL (s1, REG_ITMP3, d, 0);
816                         M_IADD (d, REG_ZERO, d, 0);
817                         store_reg_to_var_int(c->dest, d);
818                         break;
819
820                 case CMD_ISHR:
821                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
822                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
823                         d = reg_of_var(c->dest, REG_ITMP3);
824                         M_AND (s2, 0x1f, REG_ITMP3,  1);
825                         M_SRA (s1, REG_ITMP3, d,   0);
826                         store_reg_to_var_int(c->dest, d);
827                         break;
828
829                 case CMD_IUSHR:
830                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
831                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
832                         d = reg_of_var(c->dest, REG_ITMP3);
833                         M_AND    (s2, 0x1f, REG_ITMP2,  1);
834             M_ZAPNOT (s1, 0x0f, d, 1);
835                         M_SRL    ( d, REG_ITMP2, d, 0);
836                         M_IADD   ( d, REG_ZERO, d, 0);
837                         store_reg_to_var_int(c->dest, d);
838                         break;
839
840                 case CMD_LSHL:
841                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
842                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
843                         d = reg_of_var(c->dest, REG_ITMP3);
844                         M_SLL (s1, s2, d,  0);
845                         store_reg_to_var_int(c->dest, d);
846                         break;
847
848                 case CMD_LSHR:
849                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
850                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
851                         d = reg_of_var(c->dest, REG_ITMP3);
852                         M_SRA (s1, s2, d,  0);
853                         store_reg_to_var_int(c->dest, d);
854                         break;
855
856                 case CMD_LUSHR:
857                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
858                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
859                         d = reg_of_var(c->dest, REG_ITMP3);
860                         M_SRL (s1, s2, d,  0);
861                         store_reg_to_var_int(c->dest, d);
862                         break;
863
864                 case CMD_IAND:
865                 case CMD_LAND:
866                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
867                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
868                         d = reg_of_var(c->dest, REG_ITMP3);
869                         M_AND (s1, s2, d, 0);
870                         store_reg_to_var_int(c->dest, d);
871                         break;
872
873                 case CMD_IOR:
874                 case CMD_LOR:
875                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
876                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
877                         d = reg_of_var(c->dest, REG_ITMP3);
878                         M_OR   ( s1,s2, d, 0);
879                         store_reg_to_var_int(c->dest, d);
880                         break;
881
882                 case CMD_IXOR:
883                 case CMD_LXOR:
884                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
885                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
886                         d = reg_of_var(c->dest, REG_ITMP3);
887                         M_XOR (s1, s2, d, 0);
888                         store_reg_to_var_int(c->dest, d);
889                         break;
890
891
892                 case CMD_LCMP:
893                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
894                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
895                         d = reg_of_var(c->dest, REG_ITMP3);
896                         M_CMPLT  (s1, s2, REG_ITMP3, 0);
897                         M_CMPLT  (s2, s1, REG_ITMP1, 0);
898                         M_LSUB   (REG_ITMP1, REG_ITMP3, d, 0);
899                         store_reg_to_var_int(c->dest, d);
900                         break;
901                         
902
903                 /*********************** floating operations **************************/
904
905                 case CMD_FNEG:
906                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
907                         d = reg_of_var(c->dest, REG_FTMP3);
908                         M_FMOVN (s1, d);
909                         store_reg_to_var_flt(c->dest, d);
910                         break;
911                 case CMD_DNEG:
912                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
913                         d = reg_of_var(c->dest, REG_FTMP3);
914                         M_FMOVN (s1, d);
915                         store_reg_to_var_flt(c->dest, d);
916                         break;
917
918                 case CMD_FADD:
919                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
920                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
921                         d = reg_of_var(c->dest, REG_FTMP3);
922                         M_FADD ( s1,s2, d);
923                         store_reg_to_var_flt(c->dest, d);
924                         break;
925                 case CMD_DADD:
926                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
927                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
928                         d = reg_of_var(c->dest, REG_FTMP3);
929                         M_DADD (s1, s2, d);
930                         store_reg_to_var_flt(c->dest, d);
931                         break;
932
933                 case CMD_FSUB:
934                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
935                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
936                         d = reg_of_var(c->dest, REG_FTMP3);
937                         M_FSUB (s1, s2, d);
938                         store_reg_to_var_flt(c->dest, d);
939                         break;
940                 case CMD_DSUB:
941                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
942                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
943                         d = reg_of_var(c->dest, REG_FTMP3);
944                         M_DSUB (s1, s2, d);
945                         store_reg_to_var_flt(c->dest, d);
946                         break;
947
948                 case CMD_FMUL:
949                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
950                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
951                         d = reg_of_var(c->dest, REG_FTMP3);
952                         M_FMUL   (s1, s2, d);
953                         store_reg_to_var_flt(c->dest, d);
954                         break;
955                 case CMD_DMUL:
956                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
957                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
958                         d = reg_of_var(c->dest, REG_FTMP3);
959                         M_DMUL   (s1, s2, d);
960                         store_reg_to_var_flt(c->dest, d);
961                         break;
962
963                 case CMD_FDIV:
964                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
965                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
966                         d = reg_of_var(c->dest, REG_FTMP3);
967                         M_FDIV   (s1, s2, d);
968                         store_reg_to_var_flt(c->dest, d);
969                         break;
970                 case CMD_DDIV:
971                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
972                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
973                         d = reg_of_var(c->dest, REG_FTMP3);
974                         M_DDIV   (s1, s2, d);
975                         store_reg_to_var_flt(c->dest, d);
976                         break;
977                 
978                 case CMD_FREM:
979                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
980                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
981                         d = reg_of_var(c->dest, REG_FTMP3);
982                         M_FDIV   ( s1,s2, REG_FTMP3 );
983                         M_CVTDL_C ( REG_ZERO, REG_FTMP3, REG_FTMP3 ); /* round to integer */
984                         M_CVTLF ( REG_ZERO, REG_FTMP3, REG_FTMP3 );
985                         M_FMUL ( REG_FTMP3, s2, REG_FTMP3 );
986                         M_FSUB ( s1, REG_FTMP3, d);
987                         store_reg_to_var_flt(c->dest, d);
988                     break;
989                 case CMD_DREM:
990                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
991                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
992                         d = reg_of_var(c->dest, REG_FTMP3);
993                         M_DDIV   ( s1,s2, REG_FTMP3 );
994                         M_CVTDL_C ( REG_ZERO, REG_FTMP3, REG_FTMP3 ); /* round to integer */
995                         M_CVTLD ( REG_ZERO, REG_FTMP3, REG_FTMP3 );
996                         M_DMUL ( REG_FTMP3, s2, REG_FTMP3 );
997                         M_DSUB ( s1, REG_FTMP3, d);
998                         store_reg_to_var_flt(c->dest, d);
999                     break;
1000
1001                 case CMD_I2F:
1002                 case CMD_L2F:
1003                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1004                         d = reg_of_var(c->dest, REG_FTMP3);
1005                         a = dseg_adddouble(0.0);
1006                         M_LST (s1, REG_PV, a);
1007                         M_DLD (d, REG_PV, a);
1008                         M_CVTLF ( REG_ZERO, d, d);
1009                         store_reg_to_var_flt(c->dest, d);
1010                         break;
1011
1012                 case CMD_I2D:
1013                 case CMD_L2D:
1014                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1015                         d = reg_of_var(c->dest, REG_FTMP3);
1016                         a = dseg_adddouble(0.0);
1017                         M_LST (s1, REG_PV, a);
1018                         M_DLD (d, REG_PV, a);
1019                         M_CVTLD ( REG_ZERO, d, d);
1020                         store_reg_to_var_flt(c->dest, d);
1021                         break;
1022                         
1023                 case CMD_F2I:
1024                 case CMD_D2I:
1025                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
1026                         d = reg_of_var(c->dest, REG_ITMP3);
1027                         a = dseg_adddouble(0.0);
1028                         M_CVTDL_C (REG_ZERO, s1, REG_FTMP1);
1029                         M_DST (REG_FTMP1, REG_PV, a);
1030                         M_ILD (d, REG_PV, a);
1031                         store_reg_to_var_int(c->dest, d);
1032                         break;
1033                 
1034                 case CMD_F2L:
1035                 case CMD_D2L:
1036                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
1037                         d = reg_of_var(c->dest, REG_ITMP3);
1038                         a = dseg_adddouble(0.0);
1039                         M_CVTDL_C (REG_ZERO, s1, REG_FTMP1);
1040                         M_DST (REG_FTMP1, REG_PV, a);
1041                         M_LLD (d, REG_PV, a);
1042                         store_reg_to_var_int(c->dest, d);
1043                         break;
1044
1045                 case CMD_F2D:
1046                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
1047                         d = reg_of_var(c->dest, REG_FTMP3);
1048                         M_FLTMOVE (s1, d);
1049                         store_reg_to_var_flt(c->dest, d);
1050                         break;
1051                                         
1052                 case CMD_D2F:
1053                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
1054                         d = reg_of_var(c->dest, REG_FTMP3);
1055                         M_FADD (s1, REG_ZERO, d);
1056                         store_reg_to_var_flt(c->dest, d);
1057                         break;
1058                 
1059                 case CMD_FCMPL:
1060                 case CMD_DCMPL:
1061                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
1062                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
1063                         d = reg_of_var(c->dest, REG_ITMP3);
1064                         M_LSUB   (REG_ZERO, 1, d, 1);
1065                         M_FCMPEQ (s1, s2, REG_FTMP3);
1066                         M_FBEQZ  (REG_FTMP3, 1);   /* jump over next instructions         */
1067                         M_OR     (REG_ZERO, REG_ZERO, d, 0);
1068                         M_FCMPLT (s2, s1, REG_FTMP3);
1069                         M_FBEQZ  (REG_FTMP3, 1);   /* jump over next instruction          */
1070                         M_LADD   (REG_ZERO, 1, d, 1);
1071                         store_reg_to_var_int(c->dest, d);
1072                         break;
1073                         
1074                 case CMD_FCMPG:
1075                 case CMD_DCMPG:
1076                         s1 = var_to_reg_flt(c->source1, REG_FTMP1);
1077                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
1078                         d = reg_of_var(c->dest, REG_ITMP3);
1079                         M_LADD   (REG_ZERO, 1, d, 1);
1080                         M_FCMPEQ (s1, s2, REG_FTMP3);
1081                         M_FBEQZ  (REG_FTMP3, 1);   /* jump over next instruction          */
1082                         M_OR     (REG_ZERO, REG_ZERO, d, 0);
1083                         M_FCMPLT (s1, s2, REG_FTMP3);
1084                         M_FBEQZ  (REG_FTMP3, 1);   /* jump over next instruction          */
1085                         M_LSUB   (REG_ZERO, 1, d, 1);
1086                         store_reg_to_var_int(c->dest, d);
1087                         break;
1088
1089
1090                 /********************** memory operations *****************************/
1091
1092                 case CMD_ARRAYLENGTH:
1093                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1094                         d = reg_of_var(c->dest, REG_ITMP3);
1095                         M_ILD    (d, s1, OFFSET(java_arrayheader, size));
1096                         store_reg_to_var_int(c->dest, d);
1097                         break;
1098
1099                 case CMD_AALOAD:
1100                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1101                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1102                         d = reg_of_var(c->dest, REG_ITMP3);
1103                         M_S8ADDQ (s2, s1, REG_ITMP1, 0);
1104                         M_LLD    ( d, REG_ITMP1, OFFSET (java_objectarray, data[0]));
1105                         store_reg_to_var_int(c->dest, d);
1106                         break;
1107                 case CMD_LALOAD:
1108                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1109                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1110                         d = reg_of_var(c->dest, REG_ITMP3);
1111                         M_S8ADDQ (s2, s1, REG_ITMP1, 0);
1112                         M_LLD    ( d, REG_ITMP1, OFFSET (java_longarray, data[0]));
1113                         store_reg_to_var_int(c->dest, d);
1114                         break;
1115                 case CMD_IALOAD:
1116                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1117                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1118                         d = reg_of_var(c->dest, REG_ITMP3);
1119                         M_S4ADDQ (s2, s1, REG_ITMP1, 0);
1120                         M_ILD    ( d, REG_ITMP1, OFFSET (java_intarray, data[0]));
1121                         store_reg_to_var_int(c->dest, d);
1122                         break;
1123                 case CMD_FALOAD:
1124                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1125                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1126                         d = reg_of_var(c->dest, REG_FTMP3);
1127                         M_S4ADDQ (s2, s1, REG_ITMP1, 0);
1128                         M_FLD    ( d, REG_ITMP1, OFFSET (java_floatarray, data[0]));
1129                         store_reg_to_var_flt(c->dest, d);
1130                         break;
1131                 case CMD_DALOAD:
1132                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1133                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1134                         d = reg_of_var(c->dest, REG_FTMP3);
1135                         M_S8ADDQ (s2, s1, REG_ITMP1, 0);
1136                         M_DLD    ( d, REG_ITMP1, OFFSET (java_doublearray, data[0]));
1137                         store_reg_to_var_flt(c->dest, d);
1138                         break;
1139                 case CMD_CALOAD:
1140                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1141                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1142                         d = reg_of_var(c->dest, REG_ITMP3);
1143                         if (has_ext_instr_set) {
1144                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1145                                 M_LADD   (s2, REG_ITMP1, REG_ITMP1, 0);
1146                                 M_SLDU   (d, REG_ITMP1, OFFSET (java_chararray, data[0]));
1147                                 }
1148                         else {
1149                                 M_LADD   (s2, s1, REG_ITMP1,  0);
1150                                 M_LADD   (s2, REG_ITMP1, REG_ITMP1, 0);
1151                                 M_LLD_U  (REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1152                                 M_LDA    (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1153                                 M_EXTWL  (REG_ITMP2, REG_ITMP1, d, 0);
1154                                 }
1155                         store_reg_to_var_int(c->dest, d);
1156                         break;                  
1157                 case CMD_SALOAD:
1158                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1159                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1160                         d = reg_of_var(c->dest, REG_ITMP3);
1161                         if (has_ext_instr_set) {
1162                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1163                                 M_LADD   (s2, REG_ITMP1, REG_ITMP1, 0);
1164                                 M_SLDU   (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1165                                 M_SSEXT  (d, d);
1166                                 }
1167                         else {
1168                                 M_LADD   (s2, s1, REG_ITMP1,  0);
1169                                 M_LADD   (s2, REG_ITMP1, REG_ITMP1, 0);
1170                                 M_LLD_U  (REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1171                                 M_LDA    (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]) + 2);
1172                                 M_EXTQH  (REG_ITMP2, REG_ITMP1, d, 0);
1173                                 M_SRA    (d, 48, d, 1);
1174                                 }
1175                         store_reg_to_var_int(c->dest, d);
1176                         break;
1177                 case CMD_BALOAD:
1178                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1179                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1180                         d = reg_of_var(c->dest, REG_ITMP3);
1181                         if (has_ext_instr_set) {
1182                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1183                                 M_BLDU   (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1184                                 M_BSEXT  (d, d);
1185                                 }
1186                         else {
1187                                 M_LADD   (s2, s1, REG_ITMP1,  0);
1188                                 M_LLD_U  (REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1189                                 M_LDA    (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]) + 1);
1190                                 M_EXTQH  (REG_ITMP2, REG_ITMP1, d,   0);
1191                                 M_SRA    (d, 56, d,  1);
1192                                 }
1193                         store_reg_to_var_int(c->dest, d);
1194                         break;
1195
1196                 case CMD_AASTORE:
1197                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1198                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1199                         s3 = var_to_reg_int(c->source3, REG_ITMP3);
1200                         M_S8ADDQ (s2, s1, REG_ITMP1, 0);
1201                         M_LST    (s3, REG_ITMP1, OFFSET (java_objectarray, data[0]));
1202                         break;
1203                 case CMD_LASTORE:
1204                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1205                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1206                         s3 = var_to_reg_int(c->source3, REG_ITMP3);
1207                         M_S8ADDQ (s2, s1, REG_ITMP1, 0);
1208                         M_LST    (s3, REG_ITMP1, OFFSET (java_longarray, data[0]));
1209                         break;
1210                 case CMD_IASTORE:
1211                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1212                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1213                         s3 = var_to_reg_int(c->source3, REG_ITMP3);
1214                         M_S4ADDQ (s2, s1, REG_ITMP1, 0);
1215                         M_IST    (s3, REG_ITMP1, OFFSET (java_intarray, data[0]));
1216                         break;
1217                 case CMD_FASTORE:
1218                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1219                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1220                         s3 = var_to_reg_flt(c->source3, REG_FTMP3);
1221                         M_S4ADDQ (s2, s1, REG_ITMP1, 0);
1222                         M_FST    (s3, REG_ITMP1, OFFSET (java_floatarray, data[0]));
1223                         break;
1224                 case CMD_DASTORE:
1225                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1226                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1227                         s3 = var_to_reg_flt(c->source3, REG_FTMP3);
1228                         M_S8ADDQ (s2, s1, REG_ITMP1, 0);
1229                         M_DST    (s3, REG_ITMP1, OFFSET (java_doublearray, data[0]));
1230                         break;
1231                 case CMD_CASTORE:
1232                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1233                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1234                         s3 = var_to_reg_int(c->source3, REG_ITMP3);
1235                         if (has_ext_instr_set) {
1236                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1237                                 M_LADD   (s2, REG_ITMP1, REG_ITMP1, 0);
1238                                 M_SST    (s3, REG_ITMP1, OFFSET (java_chararray, data[0]));
1239                                 }
1240                         else {
1241                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1242                                 M_LADD   (s2, REG_ITMP1, REG_ITMP1, 0);
1243                                 M_LLD_U  (REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1244                                 M_LDA    (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1245                                 M_INSWL  (s3, REG_ITMP1, REG_ITMP3, 0);
1246                                 M_MSKWL  (REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1247                                 M_OR     (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1248                                 M_LST_U  (REG_ITMP2, REG_ITMP1, 0);
1249                                 }
1250                         break;
1251                 case CMD_SASTORE:
1252                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1253                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1254                         s3 = var_to_reg_int(c->source3, REG_ITMP3);
1255                         if (has_ext_instr_set) {
1256                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1257                                 M_LADD   (s2, REG_ITMP1, REG_ITMP1, 0);
1258                                 M_SST    (s3, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1259                                 }
1260                         else {
1261                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1262                                 M_LADD   (s2, REG_ITMP1, REG_ITMP1, 0);
1263                                 M_LLD_U  (REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1264                                 M_LDA    (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1265                                 M_INSWL  (s3, REG_ITMP1, REG_ITMP3, 0);
1266                                 M_MSKWL  (REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1267                                 M_OR     (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1268                                 M_LST_U  (REG_ITMP2, REG_ITMP1, 0);
1269                                 }
1270                         break;
1271                 case CMD_BASTORE:
1272                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1273                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1274                         s3 = var_to_reg_int(c->source3, REG_ITMP3);
1275                         if (has_ext_instr_set) {
1276                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1277                                 M_BST    (s3, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1278                                 }
1279                         else {
1280                                 M_LADD   (s2, s1, REG_ITMP1,  0);
1281                                 M_LLD_U  (REG_ITMP2, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1282                                 M_LDA    (REG_ITMP1, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1283                                 M_INSBL  (s3, REG_ITMP1, REG_ITMP3,     0);
1284                                 M_MSKBL  (REG_ITMP2, REG_ITMP1, REG_ITMP2,  0);
1285                                 M_OR     (REG_ITMP2, REG_ITMP3, REG_ITMP2,  0);
1286                                 M_LST_U  (REG_ITMP2, REG_ITMP1, 0);
1287                                 }
1288                         break;
1289
1290
1291                 case CMD_PUTFIELD:
1292                         switch (c->u.mem.type) {
1293                                 case TYPE_INT:
1294                                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1295                                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1296                                         M_IST (s2, s1, c->u.mem.offset);
1297                                         break;
1298                                 case TYPE_LONG:
1299                                 case TYPE_ADDRESS:
1300                                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1301                                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1302                                         M_LST (s2, s1, c->u.mem.offset);
1303                                         break;
1304                                 case TYPE_FLOAT:
1305                                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1306                                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
1307                                         M_FST (s2, s1, c->u.mem.offset);
1308                                         break;
1309                                 case TYPE_DOUBLE:
1310                                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1311                                         s2 = var_to_reg_flt(c->source2, REG_FTMP2);
1312                                         M_DST (s2, s1, c->u.mem.offset);
1313                                         break;
1314                                 default: panic ("internal error");
1315                                 }
1316                         break;
1317
1318                 case CMD_GETFIELD:
1319                         switch (c->u.mem.type) {
1320                                 case TYPE_INT:
1321                                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1322                                         d = reg_of_var(c->dest, REG_ITMP3);
1323                                         M_ILD (d, s1, c->u.mem.offset);
1324                                         store_reg_to_var_int(c->dest, d);
1325                                         break;
1326                                 case TYPE_LONG:
1327                                 case TYPE_ADDRESS:
1328                                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1329                                         d = reg_of_var(c->dest, REG_ITMP3);
1330                                         M_LLD (d, s1, c->u.mem.offset);
1331                                         store_reg_to_var_int(c->dest, d);
1332                                         break;
1333                                 case TYPE_FLOAT:
1334                                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1335                                         d = reg_of_var(c->dest, REG_FTMP1);
1336                                         M_FLD (d, s1, c->u.mem.offset);
1337                                         store_reg_to_var_flt(c->dest, d);
1338                                         break;
1339                                 case TYPE_DOUBLE:                               
1340                                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1341                                         d = reg_of_var(c->dest, REG_FTMP1);
1342                                         M_DLD (d, s1, c->u.mem.offset);
1343                                         store_reg_to_var_flt(c->dest, d);
1344                                         break;
1345                                 default: panic ("internal error");
1346                                 }
1347                         break;
1348
1349
1350                 /********************** branch operations *****************************/
1351
1352                 case CMD_GOTO:
1353                         mcode_addreference (c->u.bra.target);
1354                         M_BR (0);
1355                         break;
1356
1357                 case CMD_JSR: {
1358                         reginfo *di = c->dest->reg;
1359
1360                         if (di->typeflags & REG_INMEMORY)
1361                                 panic ("Can not put returnaddress into memory var");
1362
1363                         mcode_addreference (c->u.bra.target);
1364                         M_BSR (di->num, 0);
1365                         }
1366                         break;
1367                         
1368                 case CMD_RET:
1369                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1370                         M_RET (REG_ZERO, s1);
1371                         break;
1372
1373                 case CMD_IFEQ:
1374                 case CMD_IFEQL:
1375                 case CMD_IFNULL:
1376                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1377                         mcode_addreference (c->u.bra.target);
1378                         M_BEQZ (s1, 0);
1379                         break;
1380                 case CMD_IFLT:
1381                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1382                         mcode_addreference (c->u.bra.target);
1383                         M_BLTZ (s1, 0);
1384                         break;
1385                 case CMD_IFLE:
1386                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1387                         mcode_addreference (c->u.bra.target);
1388                         M_BLEZ (s1, 0);
1389                         break;
1390                 case CMD_IFNE:
1391                 case CMD_IFNONNULL:
1392                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1393                         mcode_addreference (c->u.bra.target);
1394                         M_BNEZ (s1, 0);
1395                         break;
1396                 case CMD_IFGT:
1397                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1398                         mcode_addreference (c->u.bra.target);
1399                         M_BGTZ (s1, 0);
1400                         break;
1401                 case CMD_IFGE:
1402                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1403                         mcode_addreference (c->u.bra.target);
1404                         M_BGEZ (s1, 0);
1405                         break;
1406
1407                 case CMD_IF_ICMPEQ:
1408                 case CMD_IF_ACMPEQ:
1409                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1410                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1411                         M_CMPEQ (s1, s2, REG_ITMP1, 0);
1412                         mcode_addreference (c->u.bra.target);
1413                         M_BNEZ (REG_ITMP1, 0);
1414                         break;
1415                 case CMD_IF_ICMPNE:
1416                 case CMD_IF_ACMPNE:
1417                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1418                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1419                         M_CMPEQ (s1, s2, REG_ITMP1, 0);
1420                         mcode_addreference (c->u.bra.target);
1421                         M_BEQZ (REG_ITMP1, 0);
1422                         break;
1423                 case CMD_IF_ICMPLT:
1424                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1425                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1426                         M_CMPLT (s1, s2, REG_ITMP1, 0);
1427                         mcode_addreference (c->u.bra.target);
1428                         M_BNEZ (REG_ITMP1, 0);
1429                         break;
1430                 case CMD_IF_ICMPGT:
1431                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1432                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1433                         M_CMPLE (s1, s2, REG_ITMP1, 0);
1434                         mcode_addreference ( c->u.bra.target );
1435                         M_BEQZ (REG_ITMP1, 0);
1436                         break;
1437                 case CMD_IF_ICMPLE:
1438                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1439                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1440                         M_CMPLE (s1, s2, REG_ITMP1, 0);
1441                         mcode_addreference (c->u.bra.target);
1442                         M_BNEZ (REG_ITMP1, 0);
1443                         break;
1444                 case CMD_IF_ICMPGE:
1445                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1446                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1447                         M_CMPLT (s1, s2, REG_ITMP1,  0);
1448                         mcode_addreference (c->u.bra.target);
1449                         M_BEQZ (REG_ITMP1, 0);
1450                         break;
1451
1452                 case CMD_IF_UCMPGE: /* branch if the unsigned value of s1 is 
1453                                        greater that s2 (note, that s2 has
1454                                        to be >= 0) */
1455                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1456                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1457                         M_CMPULE (s2, s1, REG_ITMP1, 0);
1458                         mcode_addreference (c->u.bra.target);
1459                         M_BNEZ (REG_ITMP1, 0);
1460             break;
1461
1462
1463                 case CMD_IRETURN:
1464                 case CMD_LRETURN:
1465                 case CMD_ARETURN:
1466                         s1 = var_to_reg_int(c->source1, REG_RESULT);
1467                         M_INTMOVE (s1, REG_RESULT);
1468                         goto nowperformreturn;
1469                 case CMD_FRETURN:
1470                 case CMD_DRETURN:
1471                         s1 = var_to_reg_flt(c->source1, REG_FRESULT);
1472                         M_FLTMOVE (s1, REG_FRESULT);
1473                         goto nowperformreturn;
1474
1475                 case CMD_RETURN:
1476 nowperformreturn:
1477                         {
1478                         int r, p;
1479                         
1480                         s2 = var_to_reg_int(c->source2, REG_ITMP2);
1481                         M_INTMOVE (s2, REG_EXCEPTION);
1482
1483                         p = parentargs_base;
1484                         if (!isleafmethod)
1485                                 {p--;  M_LLD (REG_RA, REG_SP, 8*p);}
1486                         for (r = INT_SAV_FST; r < INT_SAV_FST + INT_SAV_CNT; r++)
1487                                 if (!(intregs[r].typeflags & REG_ISUNUSED))
1488                                         {p--; M_LLD (r, REG_SP, 8*p);}
1489                         for (r = FLT_SAV_FST; r < FLT_SAV_FST + FLT_SAV_CNT; r++)
1490                                 if (!(floatregs[r].typeflags & REG_ISUNUSED))
1491                                         {p--; M_DLD (r, REG_SP, 8*p);}
1492
1493                         if (parentargs_base)
1494                                 {M_LDA (REG_SP, REG_SP, parentargs_base*8);}
1495                         if (runverbose) {
1496                                 M_LDA (REG_SP, REG_SP, -32);
1497                                 M_LST(REG_RA, REG_SP, 0);
1498                                 M_LST(REG_RESULT, REG_SP, 8);
1499                                 M_DST(REG_FRESULT, REG_SP,16);
1500                                 M_LST(REG_EXCEPTION, REG_SP, 24);
1501                                 a = dseg_addaddress (method);
1502                                 M_LLD(INT_ARG_FST, REG_PV, a);
1503                                 M_OR(REG_RESULT, REG_RESULT, INT_ARG_FST + 1, 0);
1504                                 M_FLTMOVE(REG_FRESULT, FLT_ARG_FST + 2);
1505                                 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
1506                                 M_LLD(REG_PV, REG_PV, a);
1507                                 M_JSR (REG_RA, REG_PV);
1508                                 if (mcodelen<=32768) M_LDA (REG_PV, REG_RA, -mcodelen);
1509                                 else {
1510                                         s4 ml=-mcodelen, mh=0;
1511                                         while (ml<-32768) { ml+=65536; mh--; }
1512                                         M_LDA (REG_PV, REG_RA, ml );
1513                                         M_LDAH (REG_PV, REG_PV, mh );
1514                                         }
1515                                 M_LLD(REG_EXCEPTION, REG_SP, 24);
1516                                 M_DLD(REG_FRESULT, REG_SP,16);
1517                                 M_LLD(REG_RESULT, REG_SP, 8);
1518                                 M_LLD(REG_RA, REG_SP, 0);
1519                                 M_LDA (REG_SP, REG_SP, 32);
1520                                 }
1521                         M_RET (REG_ZERO, REG_RA);
1522                         }
1523                         break;
1524
1525
1526                 case CMD_TABLEJUMP:
1527                         {
1528                         int i;
1529
1530                         /* build jump table top down and use address of lowest entry */
1531
1532                         a = 0;
1533                         for (i = c->u.tablejump.targetcount - 1; i >= 0; i--) {
1534                                 a = dseg_addtarget (c->u.tablejump.targets[i]);
1535                                 }
1536                         }
1537
1538                         /* last offset a returned by dseg_addtarget is used by load */
1539
1540                         s1 = var_to_reg_int(c->source1, REG_ITMP1);
1541                         M_S8ADDQ (s1, REG_PV, REG_ITMP2, 0);
1542                         M_LLD (REG_ITMP3, REG_ITMP2, a);
1543                         M_JMP (REG_ZERO, REG_ITMP3);
1544                         break;
1545
1546
1547                 case CMD_INVOKESTATIC:
1548                 case CMD_INVOKESPECIAL:
1549                 case CMD_INVOKEVIRTUAL:
1550                 case CMD_INVOKEINTERFACE:
1551                 case CMD_BUILTIN:
1552                         gen_method (c);
1553                         break;
1554
1555                 case CMD_DROP:
1556                 case CMD_ACTIVATE:
1557                         break;
1558
1559                 default: sprintf (logtext, "Unknown pseudo command: %d(%d)", c->opcode,
1560                                   c->tag);
1561                                  error();
1562         }
1563 }
1564
1565
1566 /*********************** function input_args_prealloc **************************
1567
1568         preallocates the input arguments (on the Alpha only for leaf methods)
1569
1570 *******************************************************************************/
1571
1572
1573 static void input_args_prealloc()
1574 {
1575         int     i, t;
1576         varid   p;
1577         reginfo *r;
1578
1579         if (isleafmethod)
1580                 for (i = 0; (i < mparamnum) && (i < INT_ARG_CNT); i++) {
1581                         t = mparamtypes[i];
1582                         p = mparamvars[i];
1583                         p->saved = !isleafmethod;
1584                         if (t==TYPE_DOUBLE || t==TYPE_FLOAT)
1585                                 r = &floatregs[FLT_ARG_FST + i];
1586                         else
1587                                 r = &intregs[INT_ARG_FST + i];
1588                         r->typeflags &= ~REG_ISFREEUNUSED;
1589                         p->reg = r;
1590                         }
1591 }
1592
1593
1594 /********************* function gen_computestackframe **************************
1595
1596         computes the size and the layout of a stack frame.
1597         The values of localvars_base, savedregs_base, parentargs_base 
1598     are numbers of 8-byte slots in the stackframe (every spilled or
1599     saved register value will be stored in a 64-bit slot, regardless
1600     of its type: INT/LONG/FLOAT/DOUBLE/ADDRESS)
1601         (a detailed description of the stack frame is contained in 'calling.doc')
1602
1603
1604 *******************************************************************************/
1605
1606
1607 static void gen_computestackframe()
1608 {
1609         int i;
1610
1611         savedregs_num = (isleafmethod) ? 0 : 1;   /* space to save the RA */
1612
1613         /* space to save used callee saved registers */
1614
1615         for (i = INT_SAV_FST; i < INT_SAV_FST + INT_SAV_CNT; i++)
1616                 if (! (intregs[i].typeflags & REG_ISUNUSED))
1617                         savedregs_num++;
1618         for (i = FLT_SAV_FST; i < FLT_SAV_FST + FLT_SAV_CNT; i++)
1619                 if (! (floatregs[i].typeflags & REG_ISUNUSED))
1620                         savedregs_num++;
1621
1622         localvars_base = arguments_num;
1623         savedregs_base = localvars_base + localvars_num;
1624         parentargs_base = savedregs_base + savedregs_num;
1625 }
1626
1627
1628 /******************** function gen_header **************************************
1629
1630         using the data computed by gen_computestackframe it generates a function
1631         header which:
1632         
1633                 - saves the necessary registers
1634                 - copies arguments to registers or to stack slots
1635                 
1636 *******************************************************************************/
1637
1638
1639 static void gen_header ()
1640 {
1641         int p, pa, r;
1642         reginfo *ri;
1643
1644
1645         /* create stack frame (if necessary) */
1646
1647         if (parentargs_base)
1648                 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
1649
1650         /* save return address and used callee saved registers */
1651
1652         p = parentargs_base;
1653         if (!isleafmethod)
1654                 {p--;  M_LST (REG_RA, REG_SP, 8*p);}
1655         for (r = INT_SAV_FST; r < INT_SAV_FST + INT_SAV_CNT; r++)
1656                 if (!(intregs[r].typeflags & REG_ISUNUSED))
1657                         {p--; M_LST (r, REG_SP, 8 * p);}
1658         for (r = FLT_SAV_FST; r < FLT_SAV_FST + FLT_SAV_CNT; r++)
1659                 if (!(floatregs[r].typeflags & REG_ISUNUSED))
1660                         {p--; M_DST (r, REG_SP, 8 * p);}
1661
1662         /* take arguments out of register or stack frame */
1663
1664         for (p = 0; p < mparamnum; p++) {
1665                 ri = mparamvars[p]->reg;
1666
1667                 if (p < INT_ARG_CNT) {                       /* register arguments    */
1668                         if (IS_INT_LNG_REG(ri->typeflags)) {     /* integer args          */ 
1669                                 if (!(ri->typeflags & REG_INMEMORY)) /* reg arg -> register   */
1670                                         M_INTMOVE (16+p, ri->num);
1671                                 else                                 /* reg arg -> spilled    */
1672                                         M_LST (16+p, REG_SP, 8 * (localvars_base + ri->num));
1673                                 }
1674                         else {                                   /* floating args         */   
1675                                 if (!(ri->typeflags & REG_INMEMORY)) /* reg-arg -> register   */
1676                                         M_FLTMOVE (16+p, ri->num);
1677                                 else                                             /* reg-arg -> spilled    */
1678                                         M_DST (16+p, REG_SP, 8 * (localvars_base + ri->num));
1679                                 }
1680                         }
1681
1682                 else {                                       /* stack arguments       */
1683                         pa = p - INT_ARG_CNT;
1684                         if (IS_INT_LNG_REG(ri->typeflags)) {     /* integer args          */
1685                                 if (!(ri->typeflags & REG_INMEMORY)) /* stack arg -> register */ 
1686                                         M_LLD (ri->num, REG_SP, 8 * (parentargs_base + pa));
1687                                 else {                               /* stack arg -> spilled  */
1688                                         M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
1689                                         M_LST (REG_ITMP1, REG_SP, 8 * (localvars_base + ri->num));
1690                                         }
1691                                 }
1692                         else {
1693                                 if (!(ri->typeflags & REG_INMEMORY)) /* stack-arg -> register */
1694                                         M_DLD (ri->num, REG_SP, 8 * (parentargs_base + pa) );
1695                                 else {                               /* stack-arg -> spilled  */
1696                                         M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
1697                                         M_DST (REG_FTMP1, REG_SP, 8 * (localvars_base + ri->num));
1698                                         }
1699                                 }
1700                         }
1701                 }  /* end for */
1702 }  /* end gen_header */
1703
1704
1705 /************************ function gen_resolvebranch ***************************
1706
1707         backpatches a branch instruction; Alpha branch instructions are very
1708         regular, so it is only necessary to overwrite some fixed bits in the
1709         instruction.
1710
1711         parameters: mcodepiece .. start of code area
1712                     sourcepos ... offset of branch instruction
1713                     targetpos ... offset of branch target
1714
1715 *******************************************************************************/
1716
1717
1718 static void gen_resolvebranch ( void* mcodepiece, s4 sourcepos, s4 targetpos)
1719 {
1720         s4 *command = mcodepiece;
1721         s4 offset = targetpos - (sourcepos+4);
1722
1723         (*command) |=  ((offset >> 2) & ((s4) 0x1fffff) );
1724 }
1725
1726
1727
1728 /******** redefinition of code generation makros (compilinf into array) *******/
1729
1730 /* 
1731 These macros are newly defined to allow code generation into an array.
1732 This is necessary, because the original M_.. macros generate code by
1733 calling 'mcode_adds4' that uses an additional data structure to
1734 receive the code.
1735
1736 For a faster (but less flexible) version to generate code, these
1737 macros directly use the (s4* p) - pointer to put the code directly
1738 in a locally defined array.
1739 This makes sense only for the stub-generation-routines below.
1740 */
1741
1742 #undef M_OP3
1743 #define M_OP3(op,fu,a,b,c,const) \
1744         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
1745         ((const)<<12)|((fu)<<5)|((c)) )
1746 #undef M_FOP3
1747 #define M_FOP3(op,fu,a,b,c) \
1748         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
1749 #undef M_BRA
1750 #define M_BRA(op,a,disp) \
1751         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
1752 #undef M_MEM
1753 #define M_MEM(op,a,b,disp) \
1754         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
1755
1756
1757 /************************ function createcompilerstub **************************
1758
1759         creates a stub routine which calls the compiler
1760         
1761 *******************************************************************************/
1762
1763 #define COMPSTUBSIZE 3
1764
1765 u1 *createcompilerstub (methodinfo *m)
1766 {
1767         u8 *s = CNEW (u8, COMPSTUBSIZE);    /* memory to hold the stub            */
1768         s4 *p = (s4*) s;                    /* code generation pointer            */
1769         
1770                                             /* code for the stub                  */
1771         M_LLD (REG_PV, REG_PV, 16);         /* load pointer to the compiler       */
1772         M_JMP (0, REG_PV);                  /* jump to the compiler, return address
1773                                                in reg 0 is used as method pointer */
1774         s[1] = (u8) m;                      /* literals to be adressed            */  
1775         s[2] = (u8) asm_call_jit_compiler;  /* jump directly via PV from above    */
1776
1777 #ifdef STATISTICS
1778         count_cstub_len += COMPSTUBSIZE * 8;
1779 #endif
1780
1781         return (u1*) s;
1782 }
1783
1784
1785 /************************* function removecompilerstub *************************
1786
1787      deletes a compilerstub from memory  (simply by freeing it)
1788
1789 *******************************************************************************/
1790
1791 void removecompilerstub (u1 *stub) 
1792 {
1793         CFREE (stub, COMPSTUBSIZE * 8);
1794 }
1795
1796
1797 /********************* Funktion: createnativestub ******************************
1798
1799         creates a stub routine which calls a native method
1800         
1801 *******************************************************************************/
1802
1803 #define NATIVESTUBSIZE 11
1804
1805 u1 *createnativestub (functionptr f, methodinfo *m)
1806 {
1807         u8 *s = CNEW (u8, NATIVESTUBSIZE);  /* memory to hold the stub      */
1808         s4 *p = (s4*) s;                    /* code generation pointer      */
1809
1810         M_LDA  (REG_SP, REG_SP, -8);        /* build up stackframe          */
1811         M_LST  (REG_RA, REG_SP, 0);         /* store return address         */
1812
1813         M_LLD  (REG_PV, REG_PV, 6*8);       /* load adress of native method */
1814         M_JSR  (REG_RA, REG_PV);            /* call native method           */
1815         M_LDA  (REG_PV, REG_RA, -4*4);      /* recompute pv from ra         */
1816
1817         M_LLD  (22, REG_PV, 7*8);           /* get address of exceptionptr  */
1818         M_LLD  (REG_EXCEPTION, 22, 0);      /* load exception into reg. 1   */
1819         M_LST  (REG_ZERO, 22, 0);           /* store NULL into exceptionptr */
1820
1821         M_LLD  (REG_RA, REG_SP, 0);         /* load return address          */
1822         M_LDA  (REG_SP, REG_SP, 8);         /* remove stackframe            */
1823         
1824         M_RET  (REG_ZERO, REG_RA);          /* return to caller             */
1825
1826         s[6] = (u8) f;                      /* address of native method     */
1827         s[7] = (u8) (&exceptionptr);        /* address of exceptionptr      */
1828
1829 #ifdef STATISTICS
1830         count_nstub_len += NATIVESTUBSIZE * 8;
1831 #endif
1832
1833         return (u1*) s;
1834 }
1835
1836
1837 /************************ function: removenativestub ***************************
1838
1839     removes a previously created native-stub from memory
1840     
1841 *******************************************************************************/
1842
1843 void removenativestub (u1 *stub)
1844 {
1845         CFREE (stub, NATIVESTUBSIZE * 8);
1846 }
1847