Mercurial > hg > CbC > old > device
annotate mc-code-mips.c @ 227:ed92cef127f1
*** empty log message ***
author | kono |
---|---|
date | Tue, 27 Apr 2004 18:32:28 +0900 |
parents | 6190d24e178c |
children | 0dcc0ec81ed2 |
rev | line source |
---|---|
131 | 1 /* Micro-C Code Generatation Part for MIPS (PS2Linux) */ |
130 | 2 /* $Id$ */ |
3 | |
4 #define EXTERN extern | |
5 #include "mc.h" | |
6 #include "mc-code.h" | |
7 #include "mc-codegen.h" | |
8 | |
173 | 9 char *l_include_path[] = { |
10 "/usr/include/", | |
11 0 | |
12 }; | |
13 | |
130 | 14 #define TEXT_EMIT_MODE 0 |
15 #define DATA_EMIT_MODE 1 | |
16 #define RODATA_EMIT_MODE 2 | |
17 | |
18 static void data_mode(char *name); | |
163 | 19 static void ld_indexx(int byte, int n, int xreg,int sign); |
130 | 20 static void local_table(void); |
21 static void shift(char *op, int reg); | |
22 static int struct_push(int e4,int t,int arg); | |
23 | |
24 static int output_mode = TEXT_EMIT_MODE; | |
25 static int data_alignment = 0; | |
26 | |
27 static int code_disp_label; | |
152 | 28 static int disp_label; |
130 | 29 static int r1_offset_label; |
30 static int lvar_offset_label; | |
152 | 31 static int cprestore_label; |
130 | 32 |
33 static int reg_save; | |
34 static int freg_save; | |
35 | |
149 | 36 static int freg,ireg,dreg; |
148 | 37 |
38 /* mips requires two registers for compare */ | |
39 static int cmpreg = -1; | |
40 | |
130 | 41 int size_of_int = 4; |
42 int size_of_float = 4; | |
43 int size_of_double = 8; | |
44 int size_of_longlong = 8; | |
45 int endian = 1; | |
46 | |
148 | 47 int reg_sp; /* REGister Stack-Pointer */ |
48 int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | |
49 | |
50 /* floating point registers */ | |
51 | |
52 int freg_sp; /* floating point REGister Stack-Pointer */ | |
53 int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | |
54 | |
55 /* double floating point registers */ | |
56 | |
57 int dreg_sp; /* floating point REGister Stack-Pointer */ | |
58 int dreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | |
130 | 59 |
60 #define REG_fp 1 | |
61 #define REG_sp 30 | |
62 #define REG_VAR_BASE 29 | |
131 | 63 #define REG_VAR_MIN 18 |
64 #define MIN_TMP_REG 4 | |
65 #define MAX_TMP_REG 11 | |
130 | 66 |
149 | 67 #define DREG_VAR_BASE 29 |
68 #define DREG_VAR_MIN 18 | |
69 #define MIN_TMP_DREG 4 | |
152 | 70 #define MAX_TMP_DREG 17 |
149 | 71 |
130 | 72 #define PTRC_REG 3 |
73 | |
74 #define FREG_VAR_BASE 31 | |
131 | 75 #define FREG_VAR_MIN 20 |
130 | 76 #define MIN_TMP_FREG 1 |
131 | 77 #define MAX_TMP_FREG 14 |
130 | 78 |
79 #define RET_REGISTER 3 | |
148 | 80 #define RET_FREGISTER (1+FREG_OFFSET) |
81 #define RET_DREGISTER (1+DREG_OFFSET) | |
130 | 82 |
148 | 83 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ |
130 | 84 int MAX_FREGISTER=31; |
148 | 85 int MAX_DREGISTER=16; |
86 #define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ | |
87 #define REAL_MAX_FREGISTER 32 /* PowerPCのFレジスタが32ということ*/ | |
88 #define REAL_MAX_DREGISTER 31 /* PowerPCのDレジスタ番号が31ということ*/ | |
89 | |
90 #define FREG_OFFSET REAL_MAX_REGISTER | |
91 #define DREG_OFFSET (REAL_MAX_REGISTER+REAL_MAX_FREGISTER ) | |
130 | 92 |
131 | 93 int MAX_INPUT_REGISTER_VAR = 7-MIN_TMP_REG; |
94 int MAX_CODE_INPUT_REGISTER_VAR = 7-MIN_TMP_REG; | |
130 | 95 int MAX_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; |
148 | 96 int MAX_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; |
130 | 97 int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; |
148 | 98 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; |
130 | 99 |
100 #define CREG_REGISTER MAX_TMP_REG | |
148 | 101 #define FREG_FREGISTER (MAX_TMP_FREG+FREG_OFFSET) |
149 | 102 #define DREG_DREGISTER (2+DREG_OFFSET) |
145 | 103 |
205 | 104 static int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_DREGISTER]; |
105 | |
106 static int dreg_pair0[REAL_MAX_DREGISTER] = { | |
148 | 107 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 |
108 }; | |
205 | 109 static int dreg_pair1[REAL_MAX_DREGISTER] = { |
148 | 110 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 |
111 }; | |
130 | 112 |
205 | 113 static int *regs = powerpc_regs; |
130 | 114 |
115 static int max_reg_var, max_freg_var; | |
116 | |
117 static char *reg_name[] = { | |
131 | 118 "$0","$1","$2","$3","$4","$5","$6","$7","$8","$9", |
119 "$10","$11","$12","$13","$14","$15","$16","$17","$18","$19", | |
120 "$20","$21","$22","$23","$24","$25","$26","$27","$28","$29", | |
148 | 121 "$30","$31", |
131 | 122 "$f0","$f1","$f2","$f3","$f4","$f5","$f6","$f7","$f8","$f9", |
123 "$f10","$f11","$f12","$f13","$f14","$f15","$f16","$f17","$f18","$f19", | |
124 "$f20","$f21","$f22","$f23","$f24","$f25","$f26","$f27","$f28","$f29", | |
125 "$f30","$f31" | |
130 | 126 }; |
127 | |
148 | 128 |
129 #define register_name(i) reg_name0(i) | |
130 #define fregister_name(i) reg_name0(i) | |
149 | 131 #define dregister_name0(i) reg_name1(i,dreg_pair0) |
132 #define dregister_name1(i) reg_name1(i,dreg_pair1) | |
148 | 133 |
149 | 134 static char * |
148 | 135 reg_name0(int i) |
136 { | |
137 if (i<=REAL_MAX_REGISTER+REAL_MAX_FREGISTER) | |
138 return reg_name[i]; | |
149 | 139 else { |
148 | 140 error(-1); |
149 | 141 return reg_name[0]; |
142 } | |
148 | 143 } |
144 | |
149 | 145 static char * |
151 | 146 reg_name1(int i,int *d) |
149 | 147 { |
148 if (i<=REAL_MAX_REGISTER+REAL_MAX_FREGISTER) { | |
149 error(-1); | |
150 return reg_name[0]; | |
151 } else | |
152 return reg_name[d[i-DREG_OFFSET]]; | |
153 } | |
154 | |
155 | |
148 | 156 #define is_int_reg(i) (0<=i&&i<REAL_MAX_REGISTER) |
157 #define is_float_reg(i) (REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER) | |
149 | 158 #define is_double_reg(i) (REAL_MAX_REGISTER+REAL_MAX_FREGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER+REAL_MAX_DREGISTER) |
148 | 159 |
130 | 160 |
148 | 161 int use_int(int i) { |
162 if (!is_int_reg(i)) i = ireg; | |
163 if (!regs[i]) regs[i]=1; | |
164 return i; | |
165 } | |
166 | |
167 int use_float(int i) { | |
168 if (!is_float_reg(i)) i = freg; | |
169 if (!regs[i]) regs[i]=1; | |
170 return i; | |
171 } | |
172 | |
173 int use_double(int i) { | |
174 if (!is_double_reg(i)) i = dreg; | |
175 if (!regs[i]) regs[i]=1; | |
176 return i; | |
177 } | |
130 | 178 |
195 | 179 int use_longlong(int i) { |
180 return i; | |
181 } | |
182 | |
183 #if FLOAT_CODE | |
149 | 184 static int code_d1(double d); |
185 static int code_d2(double d); | |
195 | 186 #endif |
149 | 187 |
130 | 188 static void code_save_stacks(); |
189 static void code_save_input_registers(); | |
190 static void set_creg(int,int); | |
191 static void set_freg(int,int); | |
148 | 192 static void set_dreg(int,int); |
130 | 193 |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
194 static int mask_label; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
195 static int mask1_label; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
196 static int fmask_label; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
197 static int fmask1_label; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
198 |
131 | 199 static FILE *asi; |
148 | 200 |
153 | 201 static int max_func_args; |
202 static int max_func_iargs; | |
203 static int my_func_args; | |
130 | 204 #define ARG_LVAR_OFFSET 0x10000000 |
205 | |
131 | 206 #define DOT_SIZE 1 |
207 | |
130 | 208 /* |
209 | |
152 | 210 Reorder is automatically done in assembler. |
211 delayed slot done within .set noreorder. | |
212 | |
130 | 213 r0 return value etc. |
152 | 214 $2,$3 return value. (dpcmp return value on $2) |
215 $0 special register | |
216 $4-$7 input register | |
130 | 217 r22-r29 saved register variable (input register for code segement) |
152 | 218 $31 stack pointer |
219 $fp frame pointer | |
130 | 220 |
152 | 221 $f0 return value etc. |
222 $f14,$f12 input register | |
223 $f20-$f31 saved register variable | |
130 | 224 |
225 function call stack frame | |
226 <------r1_offset------------------------------> | |
227 <------------lvar_offset-------> | |
228 r+ +------------+---+---------------+----------+--------------+----+ - | |
229 callee arg xx register save local caller arg xx | |
230 reg_save disp max_func_args*size_of_int | |
231 lvar>0 lvar<0 lvar>0x1000 0000 | |
232 | |
233 code segment stack frame | |
234 | |
235 * gotoを呼び出した関数のr1 ! r1(goto前のr1) | |
236 # * r30 <---r1_offset---------> r1 | |
237 r+ +----------+--+----------+----------------+-----------+----------+----+ | |
238 cousin arg xx reg save !callee arg !code local caller arg xx | |
239 r20-r29 lvar>0 lvar<0 lvar>0x1000 000 | |
240 f20-f31 <-my_func_args--><--disp-----><-max_func_arg-> | |
241 *size_of_int *size_of_int | |
242 | |
243 */ | |
244 int arg_offset = 24; int arg_offset1 = 24; int disp_offset = -12; | |
245 #define func_disp_offset 60 | |
246 #define r1_offset func_disp_offset+12 | |
247 int code_disp_offset = 0; int jump_offset = 0; | |
248 #define CODE_LVAR l+code_disp_offset | |
249 #define CODE_CALLER_ARG (l-ARG_LVAR_OFFSET)+arg_offset1 | |
250 #define FUNC_LVAR l+disp_offset | |
251 #define CALLER_ARG (l-ARG_LVAR_OFFSET)+arg_offset1 | |
252 #define CALLEE_ARG l+arg_offset | |
253 | |
254 void | |
255 code_offset_set() | |
256 { | |
257 #if 0 | |
258 int l; | |
259 #endif | |
260 int lvar_offsetv = -disp+max_func_args*size_of_int+func_disp_offset; | |
261 int r1_offsetv = -disp+max_func_args*size_of_int-reg_save+r1_offset; | |
153 | 262 printf("L_%d = %d\n",lvar_offset_label,lvar_offsetv); |
263 printf("L_%d = %d\n",r1_offset_label,r1_offsetv); | |
130 | 264 #if 0 |
265 printf("# function %s\n",fnptr->nm); | |
266 l = ARG_LVAR_OFFSET; | |
267 printf("# offset call0\t%d\n",CALLER_ARG); | |
268 l = ARG_LVAR_OFFSET+max_func_args*size_of_int; | |
269 printf("# offset calln\t%d %d\n",CALLER_ARG,max_func_args*size_of_int); | |
270 l = disp; | |
271 printf("# offset lvarn\t%d %d\n",FUNC_LVAR+lvar_offsetv,disp); | |
272 l = 0; | |
273 printf("# offset lvar0\t%d\n",FUNC_LVAR+lvar_offsetv); | |
274 l = -reg_save; | |
275 printf("# offset regs\t%d\n",FUNC_LVAR+lvar_offsetv); | |
276 printf("# offset r1off\t%d\n",r1_offsetv); | |
277 l = 0; | |
278 printf("# offset carg0\t%d\n",CALLEE_ARG+r1_offsetv); | |
279 l = my_func_args; | |
280 printf("# offset cargn\t%d %d\n",CALLEE_ARG+r1_offsetv,my_func_args); | |
281 #endif | |
282 } | |
283 | |
284 static void | |
131 | 285 lvar(int l) |
130 | 286 { |
287 if (fnptr->sc==CODE) { | |
148 | 288 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
289 printf("%d($fp)\n",CODE_CALLER_ARG); | |
290 } else | |
291 printf("%d($fp)\n",CODE_LVAR); | |
130 | 292 } else if (l<0) { /* local variable */ |
148 | 293 printf("%d+L_%d($fp)\n",FUNC_LVAR,lvar_offset_label); |
130 | 294 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
148 | 295 printf("%d($fp)\n",CALLER_ARG); |
130 | 296 } else { /* callee's arguments */ |
148 | 297 printf("%d+L_%d($fp)\n",CALLEE_ARG,r1_offset_label); |
130 | 298 } |
299 } | |
300 | |
301 static void | |
131 | 302 lvar_address(int l,int creg) |
130 | 303 { |
304 if (fnptr->sc==CODE) { | |
148 | 305 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
306 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_CALLER_ARG); | |
307 } else | |
308 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR); | |
130 | 309 } else if (l<0) { /* local variable */ |
148 | 310 printf("\taddu\t%s,$fp,%d+L_%d\n",register_name(creg),FUNC_LVAR,lvar_offset_label); |
130 | 311 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
148 | 312 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CALLER_ARG); |
130 | 313 } else { /* callee's arguments */ |
148 | 314 printf("\taddu\t%s,$fp,%d+L_%d\n",register_name(creg),CALLEE_ARG,r1_offset_label); |
130 | 315 } |
316 } | |
317 | |
318 void | |
319 code_lvar(int e2,int creg) { | |
131 | 320 lvar_address(e2,creg); |
130 | 321 } |
322 | |
323 void | |
324 code_init(void) | |
325 { | |
131 | 326 /* this is called once program call */ |
130 | 327 } |
328 | |
329 void | |
330 gexpr_code_init(void){ | |
331 } | |
332 | |
137 | 333 void |
148 | 334 code_gexpr(int e){ |
335 if (is_int_reg(creg) && creg!=ireg) error(-1); | |
336 } | |
337 | |
338 | |
339 void | |
137 | 340 code_arg_register(NMTBL *fnptr) |
341 { | |
342 int args = fnptr->dsp; | |
343 NMTBL *n; | |
344 int reg_var = 0; | |
345 int freg_var = 0; | |
346 int type; | |
347 int reg; | |
348 int is_code0 = is_code(fnptr); | |
130 | 349 |
137 | 350 while (args) { |
351 /* process in reverse order */ | |
352 n = (NMTBL*)caddr(args); | |
353 type = n->ty; | |
354 if (scalar(type)) { | |
355 if ((reg = get_input_register_var(reg_var,n,is_code0))) { | |
356 n->sc = REGISTER; | |
357 n->dsp = cadr(reg); | |
358 regs[n->dsp]= INPUT_REG; | |
359 reg_var++; | |
360 cadddr(args)=size_of_int; /* why we need this? */ | |
361 } | |
362 } else if (type==FLOAT) { | |
138 | 363 if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { |
141 | 364 n->sc = FREGISTER; |
137 | 365 n->dsp = cadr(reg); |
148 | 366 regs[n->dsp]= INPUT_REG; |
367 freg_var++; | |
137 | 368 cadddr(args)=size(type); /* why we need this? */ |
369 } | |
370 } else if (type==DOUBLE) { | |
141 | 371 if ((reg = get_input_dregister_var(reg_var,n,is_code0,1))) { |
137 | 372 n->sc = DREGISTER; |
373 n->dsp = cadr(reg); | |
148 | 374 regs[n->dsp]= INPUT_REG; |
141 | 375 reg_var+=2; |
137 | 376 cadddr(args)=size(type); /* why we need this? */ |
377 } | |
378 } | |
379 args = cadr(args); | |
380 } | |
130 | 381 if (is_function(fnptr)) |
148 | 382 code_save_input_registers(); |
130 | 383 } |
384 | |
385 int | |
386 get_register(void) | |
387 { /* 使われていないレジスタを調べる */ | |
388 int i,reg; | |
389 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { | |
390 if (regs[i]) continue; /* 使われている */ | |
391 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | |
392 return i; /* その場所を表す番号を返す */ | |
393 } | |
394 /* search register stack */ | |
395 for(i=0;i<reg_sp;i++) { | |
396 if ((reg=reg_stack[i])>=0) { | |
397 code_assign_lvar( | |
398 (reg_stack[i]=new_lvar(size_of_int)),reg,0); | |
399 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; | |
400 return reg; | |
401 } | |
402 } | |
195 | 403 #if FLOAT_CODE |
148 | 404 /* search dregister stack */ |
405 for(i=0;i<dreg_sp;i++) { | |
406 if ((reg=dreg_stack[i])>=0) { | |
407 code_dassign_lvar( | |
408 (dreg_stack[i]=new_lvar(size_of_double)),reg,1); | |
409 dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET; | |
149 | 410 free_register(reg); |
148 | 411 return get_register(); /* 今度は必ずある */ |
412 } | |
413 } | |
195 | 414 #endif |
131 | 415 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { |
416 reg =REG_VAR_BASE-i; | |
417 if (! regs[reg]) { /* 使われていないなら */ | |
418 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ | |
419 if (i>max_reg_var) max_reg_var=i; | |
420 return reg; | |
421 } | |
422 } | |
130 | 423 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ |
148 | 424 error(HPERR); return creg; |
130 | 425 } |
426 | |
427 int | |
428 pop_register(void) | |
429 { /* レジスタから値を取り出す */ | |
430 return reg_stack[--reg_sp]; | |
431 } | |
432 | |
195 | 433 #if FLOAT_CODE |
434 | |
148 | 435 static int |
436 get_dregister1() { | |
149 | 437 int i; |
151 | 438 for(i=MAX_TMP_DREG+DREG_OFFSET;i>MIN_TMP_DREG+DREG_OFFSET;i--) { |
148 | 439 if (regs[i]) continue; /* 使われている */ |
440 if (regs[dreg_pair0[i-DREG_OFFSET]]) continue; | |
441 if (regs[dreg_pair1[i-DREG_OFFSET]]) continue; | |
442 regs[dreg_pair0[i-DREG_OFFSET]]=USING_REG; | |
443 regs[dreg_pair1[i-DREG_OFFSET]]=USING_REG; | |
444 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | |
445 return i; /* その場所を表す番号を返す */ | |
446 } | |
447 return -1; | |
448 } | |
449 | |
450 static int | |
451 get_dregister0() | |
452 { | |
149 | 453 int reg,i; |
148 | 454 /* とりあえず、空き int register pair を探す */ |
455 if ((i=get_dregister1())!=-1) { | |
456 return i; | |
457 } | |
458 /* search dregister stack */ | |
459 for(i=0;i<dreg_sp;i++) { | |
460 if ((reg=dreg_stack[i])>=0) { | |
461 code_dassign_lvar( | |
462 (dreg_stack[i]=new_lvar(size_of_double)),reg,1); | |
463 dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET; | |
152 | 464 return reg; |
148 | 465 } |
466 } | |
467 /* clear integer register stack */ | |
468 for(i=0;i<reg_sp;i++) { | |
469 if ((reg=reg_stack[i])>=0) { | |
470 code_assign_lvar( | |
471 (reg_stack[i]=new_lvar(size_of_int)),reg,0); | |
472 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; | |
473 free_register(reg); | |
474 } | |
475 } | |
476 if ((i=get_dregister1())!=-1) { | |
477 return i; | |
478 } | |
479 | |
480 error(REG_ERR); return dreg; | |
481 } | |
482 | |
483 static int | |
484 get_fregister0() | |
130 | 485 { /* 使われていないレジスタを調べる */ |
148 | 486 int i,reg; |
487 for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { | |
488 if (regs[i]) continue; /* 使われている */ | |
489 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | |
130 | 490 return i; /* その場所を表す番号を返す */ |
491 } | |
492 /* search register stack */ | |
493 for(i=0;i<freg_sp;i++) { | |
494 if ((reg=freg_stack[i])>=0) { | |
495 code_dassign_lvar( | |
153 | 496 (freg_stack[i]=new_lvar(size_of_float)),reg,0); |
130 | 497 freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; |
498 return reg; | |
499 } | |
500 } | |
131 | 501 for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { |
148 | 502 reg =FREG_VAR_BASE-i+FREG_OFFSET; |
503 if (! regs[reg]) { /* 使われていないなら */ | |
504 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ | |
131 | 505 if (i>max_freg_var) max_freg_var=i; |
506 return reg; | |
507 } | |
508 } | |
130 | 509 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ |
510 error(REG_ERR); return freg; | |
511 } | |
512 | |
148 | 513 int |
514 get_dregister(int d) | |
149 | 515 { |
148 | 516 if (d) { |
517 return get_dregister0(); | |
518 } else { | |
519 return get_fregister0(); | |
520 } | |
521 } | |
522 | |
130 | 523 int |
524 pop_fregister(void) | |
525 { /* レジスタから値を取り出す */ | |
526 return freg_stack[--freg_sp]; | |
527 } | |
528 | |
148 | 529 int |
530 pop_dregister(void) | |
531 { /* レジスタから値を取り出す */ | |
532 return dreg_stack[--dreg_sp]; | |
533 } | |
195 | 534 #endif |
535 | |
536 #if LONGLONG_CODE | |
537 int | |
205 | 538 get_lregister() { |
539 return -1; | |
540 } | |
541 | |
542 int | |
195 | 543 get_lregister_var(NMTBL *n) |
544 { | |
204 | 545 return list2(LVAR,new_lvar(size_of_double)); |
195 | 546 } |
547 #endif | |
548 | |
148 | 549 |
130 | 550 void |
551 emit_pop_free(int xreg) | |
552 { | |
553 if (xreg>=0) | |
554 free_register(xreg); | |
555 } | |
556 | |
557 void | |
558 free_register(int i) { /* いらなくなったレジスタを開放 */ | |
148 | 559 int i0,i1; |
560 if (i<0||MAX_FREGISTER+FREG_OFFSET+REAL_MAX_DREGISTER<i) error(-1); | |
561 if (is_double_reg(i)) { | |
562 i0 = dreg_pair0[i-DREG_OFFSET]; | |
205 | 563 regs[i0]=0; |
148 | 564 i1 = dreg_pair1[i-DREG_OFFSET]; |
205 | 565 regs[i1]=0; |
148 | 566 } |
205 | 567 regs[i]=0; |
130 | 568 } |
569 | |
570 int | |
138 | 571 get_input_dregister_var(int i,NMTBL *n,int is_code,int d) |
130 | 572 { |
148 | 573 if (d) { |
574 if (is_code) { | |
575 if(!(i<DREG_VAR_BASE-DREG_VAR_MIN)) return 0; | |
576 i = DREG_VAR_BASE-i+DREG_OFFSET; | |
141 | 577 } else { |
148 | 578 if (i<0||i>=MAX_INPUT_DREGISTER_VAR) return 0; |
579 i = i+MIN_TMP_DREG+DREG_OFFSET; | |
141 | 580 } |
148 | 581 return list3(DREGISTER,i,(int)n); |
141 | 582 } else { |
148 | 583 if (is_code) { |
584 if(!(i<FREG_VAR_BASE-FREG_VAR_MIN)) return 0; | |
585 i = FREG_VAR_BASE-i+FREG_OFFSET; | |
141 | 586 } else { |
148 | 587 if (i<0||i>=MAX_INPUT_FREGISTER_VAR) return 0; |
588 i = i+MIN_TMP_FREG+FREG_OFFSET; | |
141 | 589 } |
148 | 590 return list3(FREGISTER,i,(int)n); |
141 | 591 } |
130 | 592 } |
593 | |
594 int | |
595 get_input_register_var(int i,NMTBL *n,int is_code) | |
596 { | |
597 if (is_code) { | |
131 | 598 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; |
130 | 599 i = REG_VAR_BASE-i; |
600 } else { | |
148 | 601 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; |
602 i = i+MIN_TMP_REG; | |
603 } | |
604 return list3(REGISTER,i,(int)n); | |
605 } | |
606 | |
607 /* double register case? */ | |
608 | |
609 int | |
610 get_input_register_var_1(int i,NMTBL *n,int is_code) | |
611 { | |
612 if (is_code) { | |
613 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; | |
614 i = REG_VAR_BASE-i; | |
615 } else { | |
616 if (i<0||i>=MAX_INPUT_REGISTER_VAR+1) return 0; | |
130 | 617 i = i+MIN_TMP_REG; |
618 } | |
619 return list3(REGISTER,i,(int)n); | |
620 } | |
621 | |
622 int | |
137 | 623 free_register_count(int d) |
130 | 624 { |
625 int i,count,fcount; | |
626 fcount = count = 0; | |
627 for(i=0;i<MAX_REGISTER;i++) { | |
205 | 628 if (! regs[i]) count++; |
130 | 629 } |
630 for(i=0;i<MAX_FREGISTER;i++) { | |
205 | 631 if (! regs[i+FREG_OFFSET]) fcount++; |
130 | 632 } |
148 | 633 printf("# free reg %d freg %d\n",count,fcount); |
137 | 634 return d?fcount:count; |
130 | 635 } |
636 | |
637 int | |
638 register_full(void) | |
639 { | |
640 int i; | |
641 for(i=0;i<MAX_REGISTER;i++) { | |
642 if (! regs[i]) { | |
643 return 0; | |
644 } | |
645 } | |
646 return 1; | |
647 } | |
648 | |
649 void | |
650 free_all_register(void) | |
651 { | |
652 int i; | |
205 | 653 for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; } |
654 for(i=0;i<MAX_FREGISTER;i++) { regs[i+FREG_OFFSET]=0; } | |
655 for(i=0;i<MAX_DREGISTER;i++) { regs[i+DREG_OFFSET]=0; } | |
130 | 656 creg = get_register(); |
195 | 657 #if FLOAT_CODE |
138 | 658 freg = get_dregister(0); |
150 | 659 dreg = DREG_DREGISTER; |
195 | 660 #endif |
130 | 661 set_creg(CREG_REGISTER,0); |
662 set_freg(FREG_FREGISTER,0); | |
148 | 663 set_dreg(DREG_DREGISTER,0); |
130 | 664 return; |
665 } | |
666 | |
667 void | |
668 register_usage(char *s) | |
669 { | |
670 #if 0 | |
671 int i; | |
672 #endif | |
673 if (chk) return; | |
674 if (!lsrc) return; | |
675 printf("# %d: %s:",lineno,s); | |
150 | 676 printf(" creg=%s ireg=%s freg=%s dreg=%s", |
677 is_int_reg(creg)?register_name(creg): | |
678 is_float_reg(creg)?fregister_name(creg): | |
679 is_double_reg(creg)?dregister_name0(creg):"bad", | |
680 register_name(ireg),fregister_name(freg),dregister_name0(dreg)); | |
130 | 681 #if 0 |
682 printf("\n# regs:"); | |
683 printf(":"); | |
684 for(i=0;i<MAX_REGISTER;i++) { printf("%d",regs[i]); } | |
685 printf("\n# freg:"); | |
148 | 686 for(i=0;i<MAX_FREGISTER;i++) { printf("%d",regs[i+FREG_OFFSET]); } |
130 | 687 for(i=reg_sp;i>=0;i--) { |
688 if(reg_stack[i]>=0) | |
148 | 689 printf(" %s",register_name(reg_stack[i])); |
130 | 690 } |
691 #endif | |
692 printf("\n"); | |
693 } | |
694 | |
695 void | |
696 gexpr_init(void) | |
697 { | |
698 while(reg_sp > 0) { | |
699 free_register(reg_stack[--reg_sp]); | |
700 } | |
148 | 701 while(freg_sp > 0) { |
702 free_register(freg_stack[--freg_sp]); | |
703 } | |
704 while(dreg_sp > 0) { | |
705 free_register(dreg_stack[--dreg_sp]); | |
706 } | |
707 cmpreg = -1; | |
130 | 708 text_mode(); |
709 gexpr_code_init(); | |
710 register_usage("gexpr_init"); | |
711 } | |
712 | |
713 | |
714 void | |
715 emit_init(void) | |
716 { | |
717 free_all_register(); | |
718 max_reg_var=-1; max_freg_var=-1; | |
719 reg_sp = 0; | |
720 freg_sp = 0; | |
148 | 721 dreg_sp = 0; |
130 | 722 text_mode(); |
723 } | |
724 | |
725 int | |
726 get_register_var(NMTBL *n) | |
727 { | |
728 int i; | |
729 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { | |
148 | 730 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ |
731 /* そのレジスタを使うことを宣言し */ | |
732 regs[REG_VAR_BASE-i]=USING_REG; | |
130 | 733 if (i>max_reg_var) max_reg_var=i; |
734 /* その場所を表す番号を返す */ | |
735 return list3(REGISTER,REG_VAR_BASE-i,(int)n); | |
148 | 736 } |
130 | 737 } |
738 return list2(LVAR,new_lvar(size_of_int)); | |
739 } | |
740 | |
741 int | |
742 fregister_var(int r) { | |
743 return r; | |
744 } | |
745 | |
746 int | |
138 | 747 get_dregister_var(NMTBL *n,int d) |
130 | 748 { |
148 | 749 int i,j; |
750 if (d) { | |
751 for(i=0;i<DREG_VAR_BASE-DREG_VAR_MIN;i++) { | |
149 | 752 if (! regs[j=(DREG_VAR_BASE-i+DREG_OFFSET)]) { /* 使われていないなら */ |
148 | 753 if (regs[dreg_pair0[j]] || regs[dreg_pair1[j]]) continue; |
754 regs[DREG_VAR_BASE-i+DREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/ | |
755 regs[dreg_pair0[j]] = regs[dreg_pair1[j]] = USING_REG; | |
149 | 756 if (dreg_pair1[j]>max_reg_var) max_reg_var=dreg_pair1[j]; |
148 | 757 /* その場所を表す番号を返す */ |
758 return list3(DREGISTER,DREG_VAR_BASE-i+DREG_OFFSET,(int)n); | |
759 } | |
760 } | |
761 return list2(LVAR,new_lvar(size_of_double)); | |
762 } else { | |
763 for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) { | |
764 if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* 使われていないなら */ | |
765 regs[FREG_VAR_BASE-i+FREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/ | |
766 if (i>max_freg_var) max_freg_var=i; | |
767 /* その場所を表す番号を返す */ | |
768 return list3(FREGISTER,FREG_VAR_BASE-i+FREG_OFFSET,(int)n); | |
769 } | |
770 } | |
771 return list2(LVAR,new_lvar(size_of_float)); | |
130 | 772 } |
773 } | |
774 | |
775 void | |
776 emit_push() | |
777 { | |
778 int new_reg; | |
779 if (reg_sp>MAX_MAX) error(-1); | |
780 new_reg = get_register(); | |
781 reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ | |
148 | 782 ireg = creg = new_reg; |
130 | 783 } |
784 | |
785 int | |
786 emit_pop(int type) | |
787 { | |
788 int xreg,reg; | |
789 xreg=pop_register(); | |
790 if (xreg<= -REG_LVAR_OFFSET) { | |
791 reg = get_register(); | |
792 code_rlvar(REG_LVAR_OFFSET+xreg,reg); | |
793 free_lvar(REG_LVAR_OFFSET+xreg); | |
794 xreg = reg; | |
795 } | |
796 return xreg; | |
797 } | |
798 | |
799 void | |
800 code_label(int labelno) | |
801 { | |
802 printf("L_%d:\n",labelno); | |
803 } | |
804 | |
805 void | |
806 code_gvar(int e1,int creg) { | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
807 printf("\tla %s,%s\n",register_name(creg),((NMTBL*)cadr(e1))->nm); |
130 | 808 } |
809 | |
810 void | |
811 code_rgvar(int e1,int creg) { | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
812 printf("\tlw %s,%s\n",register_name(creg),((NMTBL*)cadr(e1))->nm); |
130 | 813 } |
167 | 814 char *cload(int sign,int sz) { return sz==1?(sign?"lbu":"lb"):(sz==size_of_short?(sign?"lhu":"lh"):"lw");} |
168 | 815 char *cstore(int sz) { return sz==1?"sb":(sz==size_of_short)?"sh":"sw";} |
130 | 816 void |
167 | 817 code_crgvar(int e1,int creg,int sign,int sz){ |
818 printf("\t%s %s,%s\n",cload(sign,sz),register_name(creg),((NMTBL*)cadr(e1))->nm); | |
130 | 819 } |
820 | |
821 | |
822 void | |
823 code_register(int e2,int creg) { | |
824 if (creg!=e2) | |
148 | 825 printf("\tmove %s,%s\n",register_name(creg),register_name(e2)); |
130 | 826 } |
827 | |
828 | |
829 void | |
830 code_rlvar(int e2,int reg) { | |
131 | 831 printf("\tlw %s,",register_name(reg)); |
130 | 832 lvar(e2); |
833 } | |
834 | |
835 | |
836 void | |
167 | 837 code_crlvar(int e2,int reg,int sign,int sz) { |
838 printf("\t%s %s,",cload(sign,sz),register_name(reg)); | |
130 | 839 lvar(e2); |
840 } | |
841 | |
842 | |
843 void | |
844 code_fname(NMTBL *n,int creg) { | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
845 printf("\tla %s,%s\n",register_name(creg),n->nm); |
130 | 846 } |
847 | |
848 | |
849 void | |
850 code_const(int e2,int creg) { | |
131 | 851 printf("\tli %s,%d\n",register_name(creg),e2); |
130 | 852 } |
853 | |
854 | |
855 void | |
856 code_neg(int creg) { | |
131 | 857 printf("\tsubu %s,$0,%s\n", register_name(creg), register_name(creg)); |
130 | 858 } |
859 | |
860 | |
861 void | |
862 code_not(int creg) { | |
863 printf("\tnor %s,%s,%s\n", | |
148 | 864 register_name(creg), register_name(creg),register_name(creg)); |
130 | 865 } |
866 | |
867 | |
868 void | |
869 code_lnot(int creg) { | |
131 | 870 /* if non zero 1 else 0 */ |
871 int dreg = get_register(); | |
872 printf("\txori %s,%s,0x0\n", | |
148 | 873 register_name(dreg),register_name(creg)); |
131 | 874 printf("\tsltu %s,%s,1\n", |
148 | 875 register_name(creg),register_name(dreg)); |
131 | 876 free_register(dreg); |
130 | 877 } |
878 | |
879 void | |
168 | 880 code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) { |
130 | 881 char *xrn,*drn; |
882 int i,dreg; | |
883 if (car(e2)==REGISTER) { | |
148 | 884 printf("\taddu %s,%s,%d\n", |
168 | 885 register_name(cadr(e2)),register_name(cadr(e2)), dir); |
148 | 886 if (cadr(reg)!=e2) |
887 printf("\tmove %s,%s\n",register_name(cadr(reg)),register_name(e2)); | |
888 return; | |
130 | 889 } |
890 g_expr(e2); | |
891 xrn = register_name(creg); | |
892 dreg=get_register(); if (!dreg) error(-1); | |
893 drn = register_name(dreg); | |
168 | 894 printf("\t%s %s,0(%s)\n",cload(sign,sz),drn,xrn); |
895 printf("\taddu %s,%s,%d\n",drn,drn,dir); | |
896 printf("\t%s %s,0(%s)\n",cstore(sz),drn,xrn); | |
130 | 897 i=creg;creg=dreg;dreg=i; |
205 | 898 ireg=creg; |
130 | 899 free_register(dreg); |
900 } | |
901 | |
902 | |
903 void | |
168 | 904 code_postinc(int e1,int e2,int dir,int sign,int sz,int reg) { |
130 | 905 char *xrn,*crn,*nrn; |
906 int dreg,nreg,i; | |
907 if (car(e2)==REGISTER) { | |
148 | 908 printf("\tmove %s,%s\n",register_name(reg),register_name(cadr(e2))); |
909 printf("\taddu %s,%s,%d\n", | |
168 | 910 register_name(cadr(e2)),register_name(cadr(e2)),dir); |
148 | 911 return; |
130 | 912 } |
913 g_expr(e2); | |
914 crn = register_name(creg); | |
915 dreg=get_register(); if (!dreg) error(-1); | |
916 xrn = register_name(dreg); | |
917 nreg=get_register(); if (!nreg) error(-1); | |
918 nrn = register_name(nreg); | |
168 | 919 printf("\t%s %s,0(%s)\n",cload(sign,sz),xrn,crn); |
920 printf("\taddu %s,%s,%d\n",nrn,xrn,dir); | |
921 printf("\t%s %s,0(%s)\n",cstore(sz),nrn,crn); | |
922 i=creg;creg=dreg;dreg=i; | |
130 | 923 free_register(nreg); |
924 free_register(dreg); | |
205 | 925 ireg=creg; |
130 | 926 } |
927 | |
928 | |
929 | |
930 void | |
931 code_return(int creg) { | |
932 char *crn = register_name(creg); | |
131 | 933 printf("\tla %s,L_%d\n",crn,retcont); |
130 | 934 } |
935 | |
936 #define R1SAVE 1 | |
937 | |
938 void | |
939 code_environment(int creg) { | |
940 /* save frame pointer */ | |
941 #if R1SAVE | |
131 | 942 printf("\tlw %s,0($fp)\n",register_name(creg)); |
130 | 943 #else |
944 int l = 0; | |
131 | 945 printf("\taddu %s,",register_name(creg)); |
946 printf("$fp,%d+L_%d\n",FUNC_LVAR,lvar_offset_label); | |
130 | 947 #endif |
948 } | |
949 | |
950 void | |
951 code_bool(int e1) { | |
952 char *xrn; | |
953 int e2,e3; | |
954 b_expr(e1,1,e2=fwdlabel(),1); /* including > < ... */ | |
150 | 955 creg = use_int(creg); |
130 | 956 xrn = register_name(creg); |
957 printf("\tli %s,0\n",xrn); | |
958 jmp(e3=fwdlabel()); | |
959 fwddef(e2); | |
960 printf("\tli %s,1\n",xrn); | |
961 fwddef(e3); | |
962 } | |
963 | |
964 char * | |
965 code_gt(int cond) { | |
152 | 966 return (cond?"\tslt %s,%s,%s\n\tbeq %s,$0,L_%d\n": |
967 "\tslt %s,%s,%s\n\tbne %s,$0,L_%d\n"); | |
130 | 968 } |
969 | |
970 char * | |
971 code_ugt(int cond) { | |
152 | 972 return (cond?"\tsltu %s,%s,%s\n\tbeq %s,$0,L_%d\n": |
973 "\tsltu %s,%s,%s\n\tbne %s,$0,L_%d\n"); | |
130 | 974 } |
975 | |
976 char * | |
977 code_ge(int cond) { | |
152 | 978 return (cond?"\tslt %s,%s,%s\n\txori %s,%s,0x1\n\tbeq %s,$0,L_%d\n": |
979 "\tslt %s,%s,%s\n\txori %s,%s,0x1\n\tbne %s,$0,L_%d\n"); | |
130 | 980 } |
981 | |
982 char * | |
983 code_uge(int cond) { | |
152 | 984 return (cond?"\tsltu %s,%s,%s\n\txori %s,%s,0x1\n\tbeq %s,$0,L_%d\n": |
985 "\tsltu %s,%s,%s\n\txori %s,%s,0x1\n\tbne %s,$0,L_%d\n"); | |
130 | 986 } |
987 | |
988 char * | |
989 code_eq(int cond) { | |
152 | 990 return (cond?"\tbeq %s,%s,L_%d\n":"\tbne %s,%s,L_%d\n"); |
130 | 991 } |
992 | |
993 void | |
167 | 994 code_cmp_crgvar(int e1,int sz) { |
148 | 995 if (cmpreg==-1) cmpreg = get_register(); |
167 | 996 code_crgvar(cadr(e1),cmpreg,1,sz); |
130 | 997 } |
998 | |
999 | |
1000 void | |
167 | 1001 code_cmp_crlvar(int e2,int sz) { |
148 | 1002 if (cmpreg==-1) cmpreg = get_register(); |
167 | 1003 code_crlvar(e2,cmpreg,1,sz); |
130 | 1004 } |
1005 | |
1006 | |
1007 void | |
1008 code_cmp_rgvar(int e1) { | |
148 | 1009 if (cmpreg==-1) cmpreg = get_register(); |
1010 code_rgvar(e1,cmpreg); | |
130 | 1011 } |
1012 | |
1013 | |
1014 void | |
1015 code_cmp_rlvar(int e2) { | |
148 | 1016 if (cmpreg==-1) cmpreg = get_register(); |
149 | 1017 code_rlvar(e2,cmpreg); |
130 | 1018 } |
1019 | |
1020 | |
1021 void | |
1022 code_cmp_register(int e2) { | |
148 | 1023 cmpreg = e2; |
1024 /* prevent cmpreg freeing */ | |
130 | 1025 } |
1026 | |
1027 | |
1028 void | |
1029 ascii(char *s) | |
1030 { | |
1031 printf("\t.ascii \""); | |
1032 while(*s) { | |
1033 if (*s=='\n') | |
1034 printf("%cn",92); | |
1035 else if (*s<' ') | |
1036 printf("%c%03o",92,*s); | |
1037 else if (*s=='\\') | |
1038 printf("\\\\"); | |
1039 else if (*s==34) | |
1040 printf("%c%c",92,34); | |
1041 else | |
1042 printf("%c",*s); | |
1043 s++; | |
1044 } | |
148 | 1045 printf("\\0%c\n\t.align 2\n",34); |
130 | 1046 } |
1047 | |
1048 void | |
1049 code_string(int e1,int creg) | |
1050 { | |
1051 char *s,*crn; | |
1052 int lb; | |
1053 crn=register_name(creg); | |
1054 | |
1055 s=(char *)cadr(e1); | |
131 | 1056 printf("\t.rdata\n\t.align 2\n"); |
130 | 1057 lb=fwdlabel(); |
1058 printf("L_%d:\n",lb); | |
1059 ascii(s); | |
1060 if (output_mode==TEXT_EMIT_MODE) { | |
148 | 1061 printf(".text\n"); |
130 | 1062 } else { |
148 | 1063 text_mode(); |
130 | 1064 } |
131 | 1065 printf("\tla %s,L_%d\n",crn,lb); |
130 | 1066 } |
1067 | |
1068 #define MAX_COPY_LEN 20 | |
1069 | |
1070 void | |
1071 emit_copy(int from,int to,int length,int offset,int value,int det) | |
1072 { | |
1073 char *frn = register_name(from); | |
1074 char *trn = register_name(to); | |
1075 char *drn; | |
1076 int fix = 0; | |
1077 char *memmove = "memmove"; | |
1078 int dreg = get_register(); if (!dreg) error(-1); | |
1079 drn = register_name(dreg); | |
1080 | |
1081 /* length <0 means upward direction copy */ | |
1082 switch (length) { | |
148 | 1083 case 0: break; |
130 | 1084 case 1: case -1: |
148 | 1085 printf("\tlb %s,%d(%s)\n",drn,offset,frn); |
1086 printf("\tsb %s,%d(%s)\n",drn,offset,trn); | |
1087 break; | |
130 | 1088 case 2: case -2: |
148 | 1089 printf("\tlh %s,%d(%s)\n",drn,offset,frn); |
1090 printf("\tsh %s,%d(%s)\n",drn,offset,trn); | |
1091 break; | |
130 | 1092 case 4: case -4: |
148 | 1093 printf("\tlw %s,%d(%s)\n",drn,offset,frn); |
1094 printf("\tsw %s,%d(%s)\n",drn,offset,trn); | |
1095 break; | |
130 | 1096 default: |
148 | 1097 if (-MAX_COPY_LEN<length && length <0) { |
1098 for(;length<=4;length+=4,offset-=4) | |
1099 emit_copy(from,to,4,offset,0,det); | |
1100 for(;length<=2;length+=2,offset-=2) | |
1101 emit_copy(from,to,2,offset,0,det); | |
1102 if(length>0) | |
1103 emit_copy(from,to,length,offset,0,det); | |
1104 break; | |
1105 } else if (length <=MAX_COPY_LEN) { | |
1106 for(;length>=4;length-=4,offset+=4) | |
1107 emit_copy(from,to,4,offset,0,det); | |
1108 for(;length>=2;length-=2,offset+=2) | |
1109 emit_copy(from,to,2,offset,0,det); | |
1110 if(length>0) | |
1111 emit_copy(from,to,length,offset,0,det); | |
1112 break; | |
1113 } | |
1114 code_save_stacks(); | |
1115 printf("\tli $6,%d\n",length); | |
1116 printf("\tmr $5,%s\n",frn); | |
1117 printf("\tmr $4,%s\n",trn); | |
130 | 1118 /* overrap must be allowed */ |
148 | 1119 printf("\tbl L_%s$stub\n",memmove); |
130 | 1120 fix=0; |
148 | 1121 set_creg(RET_REGISTER,0); |
1122 if (creg!=to) { | |
1123 free_register(to); to = creg; | |
1124 } | |
1125 break; | |
130 | 1126 } |
149 | 1127 if (value) { |
130 | 1128 /* creg must point top of the destination data */ |
1129 /* this code is necessary for the value of assignment or function call */ | |
1130 /* otherwise we don't need this */ | |
148 | 1131 if (fix) printf("\taddi %s,%s,%d\n",trn,trn,fix); |
1132 if(creg!=to) { | |
1133 free_register(creg); creg=to; | |
1134 } | |
130 | 1135 } |
1136 free_register(dreg); | |
1137 } | |
1138 | |
1139 int | |
1140 struct_push(int e4,int t,int arg) | |
1141 { | |
1142 int length,count; | |
1143 int dreg,sreg; char *drn,*crn,*srn; | |
1144 g_expr(e4); | |
1145 length=size(t); | |
1146 if(length%size_of_int) { | |
1147 length += size_of_int - (length%size_of_int); | |
1148 } | |
1149 dreg = get_register(); if (!dreg) error(-1); | |
1150 drn = register_name(dreg); | |
1151 crn = register_name(creg); | |
1152 if (length<MAX_COPY_LEN) { | |
1153 sreg = get_register(); if (!sreg) error(-1); | |
1154 srn = register_name(sreg); | |
1155 code_lvar(cadr(arg),sreg); | |
1156 for(count=0;length<MAX_COPY_LEN;count++,length-=size_of_int) { | |
1157 if (length==0) { | |
1158 free_register(sreg); | |
1159 free_register(dreg); | |
1160 return count; | |
1161 } else { | |
148 | 1162 printf("\tlw %s,%d(%s)\n",drn,length-size_of_int,crn); |
1163 printf("\tsw %s,%d(%s)\n",drn,length-size_of_int,srn); | |
130 | 1164 } |
1165 } | |
1166 } | |
1167 code_lvar(cadr(arg),dreg); | |
1168 /* downward direction copy */ | |
1169 emit_copy(creg,dreg,length,0,0,1); | |
1170 if (dreg) free_register(dreg); | |
1171 return length/size_of_int; | |
1172 } | |
1173 | |
1174 void | |
1175 set_creg(int reg,int mode) | |
1176 { | |
148 | 1177 if (!is_int_reg(reg)) error(-1); |
130 | 1178 if (reg!=creg) { |
148 | 1179 if (reg!=ireg && mode) |
150 | 1180 printf("\tmove %s,%s\n",register_name(reg),register_name(ireg)); |
130 | 1181 free_register(creg); |
148 | 1182 creg = ireg = reg; |
130 | 1183 regs[creg]=1; |
1184 } | |
1185 } | |
1186 | |
1187 void | |
1188 set_freg(int reg,int mode) | |
1189 { | |
148 | 1190 if (!is_float_reg(reg)) error(-1); |
1191 if (reg!=creg) { | |
1192 if (reg!=freg && mode) { | |
1193 printf("\tfmove %s,%s\n",fregister_name(reg),fregister_name(freg)); | |
1194 } | |
1195 free_register(creg); | |
1196 creg = freg = reg; | |
1197 regs[freg]=1; | |
130 | 1198 } |
1199 } | |
1200 | |
149 | 1201 static void |
1202 move_dreg(int reg,int dreg) | |
1203 { | |
1204 if (reg!=dreg) { | |
1205 printf("\tmove %s,%s\n",dregister_name0(reg), | |
1206 dregister_name0(dreg)); | |
1207 printf("\tmove %s,%s\n",dregister_name1(reg), | |
1208 dregister_name1(dreg)); | |
1209 } | |
1210 } | |
1211 | |
130 | 1212 void |
148 | 1213 set_dreg(int reg,int mode) |
1214 { | |
1215 if (!is_double_reg(reg)) error(-1); | |
1216 if (reg!=creg) { | |
149 | 1217 if (mode) { |
1218 move_dreg(reg,dreg); | |
148 | 1219 } |
1220 free_register(creg); | |
1221 creg = dreg = reg; | |
1222 regs[dreg]=1; | |
152 | 1223 regs[dreg_pair0[dreg-DREG_OFFSET]]=1; |
1224 regs[dreg_pair1[dreg-DREG_OFFSET]]=1; | |
148 | 1225 } |
1226 } | |
1227 | |
1228 | |
1229 void | |
130 | 1230 use_var(int arg) |
1231 { | |
1232 if (car(arg)==REGISTER) | |
1233 regs[cadr(arg)]=USING_REG; | |
148 | 1234 else if (car(arg)==FREGISTER) |
1235 regs[cadr(arg)]=USING_REG; | |
130 | 1236 else if (car(arg)==DREGISTER) |
148 | 1237 regs[cadr(arg)]=USING_REG; |
130 | 1238 } |
1239 | |
1240 void | |
1241 code_save_input_registers() | |
1242 { | |
1243 int args; | |
1244 NMTBL *n; | |
1245 int reg; | |
1246 int tag; | |
1247 int lvar; | |
1248 int t; | |
1249 /* fnptr->dsp=list4(type,fnptr->dsp,(int)n,0); */ | |
1250 int reg_offset = 0; | |
1251 int offset = 0; | |
1252 | |
1253 for(args = fnptr->dsp;args;args = cadr(args)) { | |
1254 n = (NMTBL *)caddr(args); | |
1255 tag = n->sc; | |
1256 reg = n->dsp; | |
1257 if (!n||n==&null_nptr) error(REG_ERR); | |
1258 if (tag==REGISTER) { | |
1259 /* regs[reg]==INPUT_REG case should be considered */ | |
1260 n->dsp = offset; | |
1261 offset+=size_of_int; | |
1262 t = INT; | |
1263 reg += reg_offset; /* for duplicated floating point argument */ | |
148 | 1264 } else if (tag==FREGISTER) { |
1265 /* fregs[reg]==INPUT_REG case should be considered */ | |
1266 n->dsp = offset; | |
1267 t = n->ty; | |
1268 if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } | |
1269 else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } | |
1270 else error(-1); | |
1271 } else if (tag==DREGISTER) { | |
1272 /* fregs[reg]==INPUT_REG case should be considered */ | |
1273 n->dsp = offset; | |
1274 t = n->ty; | |
1275 if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } | |
1276 else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } | |
1277 else error(-1); | |
130 | 1278 } else { |
1279 offset += size(n->ty); | |
1280 continue; | |
1281 } | |
1282 n->sc = LVAR; | |
1283 lvar = list2(LVAR,n->dsp); | |
1284 g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),n->ty,t)); | |
148 | 1285 if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER) { |
130 | 1286 free_register(reg); |
1287 } | |
1288 } | |
1289 my_func_args = offset; | |
1290 } | |
1291 | |
1292 int | |
1293 simple_args(int e3) | |
1294 { | |
1295 return | |
1296 !contains_in_list(e3,FUNCTION) && | |
1297 !contains_in_list(e3,CONV) && | |
1298 !contains_in_list(e3,RSTRUCT) && | |
164 | 1299 !contains_in_list(e3,STASS) |
130 | 1300 ; |
1301 } | |
1302 | |
1303 int | |
1304 caller_arg_offset_v(int arg) | |
1305 { | |
1306 return ARG_LVAR_OFFSET+arg*size_of_int; | |
1307 } | |
1308 | |
1309 int | |
1310 function(int e1) | |
1311 { | |
150 | 1312 int e2,e3,e4,nargs,t; |
130 | 1313 int arg,reg_arg,freg_arg,arg_assign; |
148 | 1314 int dots; |
130 | 1315 int reg_arg_list=0,ret_type,special_lvar; |
1316 NMTBL *fn = 0; | |
1317 int jmp = 0; | |
1318 char *jrn; | |
153 | 1319 int iargs=0; |
130 | 1320 |
1321 special_lvar = -1; | |
148 | 1322 ret_type = cadr(cadddr(e1)); |
1323 if (ret_type==CHAR) ret_type=INT; | |
1324 | |
1325 /* check argments type is DOTS? */ | |
1326 t = caddr(cadddr(e1)); | |
1327 if (t==0 || t==DOTS) dots = 1; | |
1328 else { | |
1329 dots = 0; | |
1330 for(t = caddr(cadddr(e1));t;t = cadr(t)) { | |
1331 if (car(t)==DOTS) dots = 1; | |
1332 } | |
1333 } | |
130 | 1334 |
1335 e2 = cadr(e1); | |
1336 if (car(e2) == FNAME) { | |
1337 fn=(NMTBL *)cadr(e2); | |
1338 } else { | |
1339 jmp = get_register_var(0); | |
1340 if (car(jmp)!=REGISTER) error(-1); | |
1341 reg_arg_list = list2(jmp,reg_arg_list); | |
1342 g_expr(e2); | |
1343 code_register(creg,cadr(jmp)); | |
1344 /* g_expr(assign_expr0(jmp,e2,INT,INT)); functions are lvalue */ | |
1345 } | |
1346 | |
1347 /* now all input register vars are free */ | |
1348 code_save_stacks(); | |
1349 set_creg(CREG_REGISTER,0); | |
1350 set_freg(FREG_FREGISTER,0); | |
148 | 1351 set_dreg(DREG_DREGISTER,0); |
130 | 1352 |
1353 nargs = reg_arg = freg_arg = arg_assign = 0; | |
1354 for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { | |
1355 t=caddr(e3); | |
1356 e4 = car(e3); | |
1357 if(scalar(t)) { | |
1358 if (reg_arg>=MAX_INPUT_REGISTER_VAR) { | |
1359 arg = list2(LVAR,caller_arg_offset_v(nargs)); | |
1360 } else if (!simple_args(e3) && cadr(e3)) { | |
1361 arg = get_register_var(0); | |
1362 arg_assign = list2( | |
148 | 1363 assign_expr0(get_input_register_var(reg_arg,0,0), |
1364 arg,t,t), | |
130 | 1365 arg_assign); |
1366 } else { | |
1367 arg = get_input_register_var(reg_arg,0,0); | |
1368 } | |
1369 use_var(arg); /* protect from input register free */ | |
1370 reg_arg_list = list2(arg,reg_arg_list); | |
1371 g_expr_u(assign_expr0(arg,e4,t,t)); | |
153 | 1372 nargs ++ ; reg_arg++; iargs += size_of_int; |
130 | 1373 continue; |
1374 } else if (t==DOUBLE||t==FLOAT) { | |
1375 if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { | |
1376 arg = list2(LVAR,caller_arg_offset_v(nargs)); | |
148 | 1377 } else if (!simple_args(e3) && cadr(e3)) { |
138 | 1378 arg = get_dregister_var(0,1); |
130 | 1379 arg_assign = list2( |
148 | 1380 assign_expr0(get_input_dregister_var(freg_arg,0,0,1), |
1381 arg,t,t), | |
130 | 1382 arg_assign); |
1383 } else { | |
138 | 1384 arg = get_input_dregister_var(freg_arg,0,0,1); |
130 | 1385 } |
1386 use_var(arg); /* protect from input register free */ | |
1387 reg_arg_list = list2(arg,reg_arg_list); | |
1388 g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ | |
1389 freg_arg++; | |
1390 nargs += size(t)/size_of_int; | |
153 | 1391 if (t==DOUBLE) iargs += size(t); |
130 | 1392 continue; |
1393 } else if (car(t)==STRUCT||car(t)==UNION) { | |
1394 arg = list2(LVAR,caller_arg_offset_v(nargs)); | |
1395 nargs += struct_push(e4,t,arg); | |
153 | 1396 iargs += ((size(t)+3)/size_of_int)*size_of_int; |
130 | 1397 continue; |
1398 } else { | |
1399 error(TYERR); | |
1400 } | |
1401 ++nargs; | |
1402 } | |
1403 if (max_func_args<nargs) max_func_args=nargs; | |
153 | 1404 if (max_func_iargs<iargs) max_func_iargs=iargs; |
130 | 1405 for(;arg_assign;arg_assign=cadr(arg_assign)) { |
1406 g_expr_u(car(arg_assign)); | |
1407 } | |
1408 if (car(e2) == FNAME) { | |
1409 printf("\tbl\tL_%s$stub\n",fn->nm); | |
1410 } else { | |
1411 jrn = register_name(cadr(jmp)); | |
131 | 1412 printf("\tj %s\n",jrn); |
130 | 1413 } |
1414 for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) { | |
1415 arg = car(reg_arg_list); | |
148 | 1416 if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER) |
1417 free_register(cadr(arg)); | |
130 | 1418 else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); |
1419 } | |
148 | 1420 if (ret_type==DOUBLE) { |
1421 set_dreg(RET_DREGISTER,0); | |
1422 } else if (ret_type==FLOAT) { | |
130 | 1423 set_freg(RET_FREGISTER,0); |
1424 } else if (ret_type==VOID) { | |
1425 } else { | |
1426 set_creg(RET_REGISTER,0); | |
1427 } | |
1428 return ret_type; | |
1429 } | |
1430 | |
1431 void | |
1432 code_frame_pointer(int e3) { | |
1433 #if R1SAVE | |
131 | 1434 printf("\tmove $fp,%s\n",register_name(e3)); |
130 | 1435 #else |
131 | 1436 printf("\tmove $fp,%s\n",register_name(e3)); |
130 | 1437 #endif |
1438 } | |
1439 | |
1440 | |
1441 void | |
1442 code_fix_frame_pointer(int disp_offset) { | |
1443 int l = 0; | |
131 | 1444 printf("\tla $fp,"); |
1445 printf("%d+L_%d($sp)\n",FUNC_LVAR,lvar_offset_label); | |
130 | 1446 } |
1447 | |
1448 void | |
1449 code_jmp(char *s) { | |
1450 max_reg_var = REG_VAR_BASE-REG_VAR_MIN; | |
1451 max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; | |
131 | 1452 printf("\tj L_%s\n",s); |
130 | 1453 } |
1454 | |
1455 | |
1456 void | |
1457 code_indirect_jmp(int e2) { | |
1458 max_reg_var = REG_VAR_BASE-REG_VAR_MIN; | |
1459 max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; | |
131 | 1460 printf("\tj %s\n",register_name(e2)); |
130 | 1461 } |
1462 | |
1463 int | |
196 | 1464 code_rindirect(int e1, int offset, int us) |
1465 { | |
1466 char *crn; | |
1467 g_expr(e1); | |
1468 crn=register_name(creg); | |
1469 printf("\tlw %s,%d(%s)\n",crn,offset,crn); | |
1470 return INT; | |
1471 } | |
1472 | |
1473 int | |
1474 code_crindirect(int e1, int offset, int us) | |
130 | 1475 { |
1476 char *crn; | |
196 | 1477 g_expr(e1); |
1478 crn=register_name(creg); | |
1479 if (us) { | |
1480 printf("\tlbu %s,%d(%s)\n",crn,offset,crn); | |
1481 return UCHAR; | |
1482 } else { | |
1483 printf("\tlb %s,%d(%s)\n",crn,offset,crn); | |
1484 return CHAR; | |
130 | 1485 } |
196 | 1486 } |
1487 | |
1488 int | |
1489 code_srindirect(int e1, int offset, int us) | |
1490 { | |
1491 char *crn; | |
1492 g_expr(e1); | |
130 | 1493 crn=register_name(creg); |
196 | 1494 if (us) { |
1495 printf("\tlhu %s,%d(%s)\n",crn,offset,crn); | |
1496 return USHORT; | |
1497 } else { | |
1498 printf("\tlh %s,%d(%s)\n",crn,offset,crn); | |
1499 return SHORT; | |
1500 } | |
1501 } | |
1502 | |
1503 #if FLOAT_CODE | |
1504 int | |
1505 code_drindirect(int e1, int offset, int d) | |
1506 { | |
1507 char *crn; | |
1508 g_expr(e1); | |
1509 crn=register_name(creg); | |
1510 if (d) { | |
149 | 1511 printf("\tlw %s,%d(%s)\n", |
1512 dregister_name0(dreg),offset,crn); | |
1513 printf("\tlw %s,%d(%s)\n", | |
1514 dregister_name1(dreg),offset+size_of_int,crn); | |
1515 creg = dreg; | |
148 | 1516 return DOUBLE; |
196 | 1517 } else { |
1518 printf("\tl.s %s,%d(%s)\n", fregister_name(freg),offset,crn); | |
1519 creg = freg; | |
1520 return FLOAT; | |
130 | 1521 } |
1522 } | |
196 | 1523 #endif |
1524 | |
1525 #if LONGLONG_CODE | |
1526 int | |
1527 code_lrindirect(int e1, int offset, int us) | |
1528 { | |
1529 char *crn; | |
1530 g_expr(e1); | |
1531 crn=register_name(creg); | |
203 | 1532 return LONGLONG; |
196 | 1533 } |
1534 #endif | |
130 | 1535 |
1536 void | |
1537 code_assign_gvar(int e2,int creg,int byte) { | |
151 | 1538 char *crn,*name; |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
1539 |
151 | 1540 name = ((NMTBL*)cadr(e2))->nm; |
130 | 1541 crn=register_name(creg); |
167 | 1542 if (byte==1) { |
151 | 1543 printf("\tsb %s,%s\n",crn,name); |
167 | 1544 } if (byte==size_of_short) { |
1545 printf("\tsh %s,%s\n",crn,name); | |
130 | 1546 } else { |
151 | 1547 printf("\tsw %s,%s\n",crn,name); |
130 | 1548 } |
1549 } | |
1550 | |
1551 void | |
1552 code_assign_lvar(int e2,int creg,int byte) { | |
1553 char *crn; | |
1554 crn=register_name(creg); | |
167 | 1555 if (byte==1) { |
1556 printf("\tsb %s,",crn); | |
1557 } else if (byte==size_of_short) { | |
1558 printf("\tsh %s,",crn); | |
130 | 1559 } else { |
167 | 1560 printf("\tsw %s,",crn); |
130 | 1561 } |
167 | 1562 lvar(e2); |
130 | 1563 } |
1564 | |
1565 void | |
1566 code_assign_register(int e2,int byte,int creg) { | |
1567 if (e2!=creg) | |
148 | 1568 printf("\tmove %s,%s\n",register_name(e2),register_name(creg)); |
130 | 1569 } |
1570 | |
1571 void | |
1572 code_assign(int e2,int byte,int creg) { | |
1573 char *drn=register_name(e2); | |
1574 char *crn=register_name(creg); | |
1575 | |
167 | 1576 if (byte==1) { |
148 | 1577 printf("\tsb %s,0(%s)\n",crn,drn); |
167 | 1578 } else if (byte==size_of_short) { |
1579 printf("\tsh %s,0(%s)\n",crn,drn); | |
130 | 1580 } else { |
148 | 1581 printf("\tsw %s,0(%s)\n",crn,drn); |
130 | 1582 } |
1583 } | |
1584 | |
1585 | |
1586 void | |
1587 code_register_assop(int e2,int op,int byte) { | |
1588 int reg; | |
1589 int xreg = creg; | |
1590 creg = reg = e2; | |
1591 tosop(op,xreg); | |
1592 creg = xreg; | |
1593 if (creg!=reg) | |
148 | 1594 printf("\tmove %s,%s\n",register_name(creg),register_name(reg)); |
130 | 1595 } |
1596 | |
1597 | |
1598 void | |
163 | 1599 code_assop(int op,int byte,int sign) { |
130 | 1600 char *xrn,*crn,*drn; |
1601 int xreg; | |
1602 int edx = get_register(); if(!edx) error(-1); | |
1603 xrn = register_name(xreg = emit_pop(0)); /* pop e3 value */ | |
205 | 1604 regs[xreg]=1; |
130 | 1605 printf("# assop\n\tmr %s,%s\n",register_name(edx),register_name(creg)); |
163 | 1606 ld_indexx(byte,0,edx,sign); |
130 | 1607 tosop(op,xreg); |
1608 crn = register_name(creg); | |
1609 drn = register_name(edx); | |
168 | 1610 printf("\t%s %s,0(%s)\n",cstore(byte),crn,drn); |
130 | 1611 free_register(edx); |
1612 emit_pop_free(xreg); | |
1613 } | |
1614 | |
1615 | |
1616 void | |
1617 tosop(int op,int oreg) | |
1618 { | |
1619 int dx; | |
149 | 1620 char *orn,*crn; |
130 | 1621 |
1622 if(oreg==-1) { | |
1623 error(-1); | |
1624 } else if (oreg<= -REG_LVAR_OFFSET) { | |
1625 dx = get_register(); if (dx<0) error(-1); | |
1626 code_rlvar(oreg+REG_LVAR_OFFSET,dx); | |
1627 oreg = dx; | |
1628 } | |
1629 | |
1630 switch(op) { | |
1631 case LSHIFT: | |
1632 case ULSHIFT: | |
131 | 1633 shift("sll",oreg); |
130 | 1634 return; |
1635 case RSHIFT: | |
131 | 1636 shift("srl",oreg); |
130 | 1637 return; |
1638 case URSHIFT: | |
131 | 1639 shift("sra",oreg); |
130 | 1640 return; |
1641 } | |
1642 orn = register_name(oreg); | |
1643 crn = register_name(creg); | |
1644 switch(op) { | |
1645 case ADD: | |
131 | 1646 printf("\taddu %s,%s,%s\n",crn,crn,orn); |
130 | 1647 break; |
1648 case SUB: | |
131 | 1649 printf("\tsubu %s,%s,%s\n",crn,crn,orn); |
130 | 1650 break; |
1651 case CMP: | |
131 | 1652 printf("\tslt %s,%s\n",crn,orn); |
130 | 1653 break; |
1654 case BAND: | |
1655 printf("\tand %s,%s,%s\n",crn,crn,orn); | |
1656 break; | |
1657 case EOR: | |
1658 printf("\txor %s,%s,%s\n",crn,crn,orn); | |
1659 break; | |
1660 case BOR: | |
1661 printf("\tor %s,%s,%s\n",crn,crn,orn); | |
1662 break; | |
1663 case MUL: | |
131 | 1664 printf("\tmult %s,%s,%s\n",crn,crn,orn); |
130 | 1665 break; |
1666 case UMUL: | |
131 | 1667 printf("\tmultu %s,%s,%s\n",crn,crn,orn); |
130 | 1668 break; |
148 | 1669 case DIV: |
1670 printf("\tdivw %s,%s,%s\n",crn,crn,orn); | |
1671 break; | |
149 | 1672 case UDIV: case MOD: case UMOD: |
148 | 1673 printf("\t%s $0,%s,%s\n",(op==UDIV||op==UMOD)?"divu":"div",crn,orn); |
1674 printf("\t%s %s\n",(op==MOD||op==UMOD)?"mflo":"mfhi",crn); | |
1675 printf("\t.set noreorder\n"); | |
1676 printf("\tbeql %s,$0,1f\n",orn); | |
1677 printf("\tbreak 7\n"); | |
1678 printf("1:\n"); | |
1679 printf("\t.set reorder\n"); | |
1680 break; | |
130 | 1681 default: |
1682 error(-1); | |
1683 } | |
1684 if(oreg!=creg) free_register(oreg); | |
1685 } | |
1686 | |
1687 | |
1688 void | |
1689 shift(char *op, int reg) | |
1690 { | |
1691 char *crn = register_name(creg); | |
1692 char *rrn = register_name(reg); | |
1693 printf("\t%s %s,%s,%s\n",op,crn,rrn,crn); | |
1694 } | |
1695 | |
189 | 1696 int |
1697 code_const_op_p(int op,int v) | |
1698 { | |
1699 if (op==BAND||op==DIV||op==UDIV||op==MOD||op==UMOD) return 0; | |
1700 return 0; | |
1701 } | |
1702 | |
1703 void | |
1704 oprtc(int op,int v) | |
1705 { | |
1706 } | |
1707 | |
1708 | |
130 | 1709 void |
163 | 1710 ld_indexx(int byte, int n, int xreg,int sign) |
130 | 1711 { |
1712 char *crn = register_name(creg); | |
168 | 1713 printf("\t%s %s,%d(%s)\n",cload(sign,byte),crn,n, |
1714 register_name(xreg)); | |
130 | 1715 } |
1716 | |
1717 int | |
1718 code_csvalue() | |
1719 { | |
1720 return creg; | |
1721 } | |
1722 | |
1723 void | |
1724 code_cmpdimm(int e, int csreg) | |
1725 { | |
1726 /* used in dosiwtch() */ | |
1727 if(chk) return; | |
150 | 1728 creg = use_int(creg); |
131 | 1729 printf("\tli %s,%d\n",register_name(creg),e); |
148 | 1730 cmpreg = csreg; |
130 | 1731 } |
1732 | |
1733 void | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
1734 code_opening(char *s) |
130 | 1735 { |
131 | 1736 /* this is called once per month */ |
1737 char *p=cheapp; | |
1738 | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
1739 printf("\t.file \"%s\"\n",s); |
130 | 1740 /* printf("\t.version\t\"01.01\"\n"); */ |
1741 /* printf("gcc2_compiled.:\n"); */ | |
131 | 1742 printf("\t.abicalls\n"); |
1743 printf("\t.text\n"); | |
1744 | |
1745 if (asi) { | |
148 | 1746 fclose(asi); |
1747 asi = 0; | |
131 | 1748 } |
1749 while ((*cheapp++ = *s++)) { | |
1750 if (*s=='.') { | |
1751 *cheapp++=*s++; *cheapp++='i'; | |
148 | 1752 *cheapp++=0; |
131 | 1753 break; |
1754 } | |
1755 } | |
1756 asi = fopen(p,"w"); | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
1757 printf(".include \"%s\"\n",p); |
131 | 1758 if (!asi) error(-1); |
130 | 1759 } |
1760 | |
1761 void | |
1762 rexpr(int e1, int l1, char *s,int t) | |
1763 { | |
132 | 1764 char *crn,*drn; |
148 | 1765 if (cmpreg>=0) { free_register(cmpreg); cmpreg = -1; } |
132 | 1766 |
1767 g_expr(cadr(e1)); | |
1768 emit_push(); | |
1769 g_expr(caddr(e1)); | |
150 | 1770 cmpreg = emit_pop(0); |
132 | 1771 crn = register_name(creg); |
148 | 1772 drn = register_name(cmpreg); |
132 | 1773 |
1774 if (s[1] == 's') { | |
148 | 1775 if (s[16]=='x') { |
1776 /* slt $2,$2,$3; xroi $2,$2,0x1; beq $2,$0,L1 */ | |
1777 printf(s,crn,drn,drn,crn,crn,crn,l1); | |
1778 } else { | |
1779 /* slt $2,$2,$3; beq $2,$0,L1 */ | |
1780 printf(s,crn,drn,drn,crn,l1); | |
1781 } | |
132 | 1782 } else { |
148 | 1783 /* beq $2,$3,L1 */ |
1784 printf(s,crn,drn,l1); | |
132 | 1785 } |
148 | 1786 free_register(cmpreg) ; cmpreg = -1; |
130 | 1787 } |
1788 | |
1789 void | |
1790 jcond(int l, char cond) | |
131 | 1791 { |
130 | 1792 if (chk) return; |
148 | 1793 if (cmpreg==-1) error(-1); |
150 | 1794 printf("\tb%s %s,%s,L_%d\n", |
1795 cond?"ne":"eq", | |
1796 register_name(creg),register_name(cmpreg), | |
1797 l); | |
205 | 1798 free_register(cmpreg); cmpreg = -1; |
130 | 1799 } |
1800 | |
1801 void | |
1802 jmp(int l) | |
1803 { | |
1804 control=0; | |
1805 if (chk) return; | |
131 | 1806 printf("\tj\tL_%d\n",l); |
130 | 1807 } |
1808 | |
1809 void | |
1810 gen_comment(char *s) | |
1811 { | |
1812 if (chk) return; | |
1813 printf("## %s",s); | |
1814 } | |
1815 | |
1816 void | |
1817 code_enter(char *name) | |
1818 { | |
1819 if (output_mode!=TEXT_EMIT_MODE) | |
1820 text_mode(); | |
1821 else | |
132 | 1822 printf("\t.align 3\n"); |
153 | 1823 /* if (stmode!=STATIC) |
1824 printf(".globl _%s\n",name); */ | |
132 | 1825 printf(".ent %s\n",name); |
130 | 1826 printf("_%s:\n",name); |
1827 code_disp_label=fwdlabel(); | |
132 | 1828 |
1829 printf("\t.set noreorder\n"); | |
1830 printf("\t.cpload $25\n"); | |
1831 printf("\t.set reorder\n"); | |
1832 printf("\tsubu $sp,$sp,L_%d\n",code_disp_label); | |
153 | 1833 printf("\t.cprestore L_%d\n",cprestore_label); |
148 | 1834 |
130 | 1835 max_func_args = 0; |
153 | 1836 max_func_iargs = 0; |
130 | 1837 } |
1838 | |
1839 | |
1840 void | |
1841 code_enter1(int args) | |
1842 { | |
1843 set_creg(CREG_REGISTER,0); | |
1844 set_freg(FREG_FREGISTER,0); | |
148 | 1845 set_dreg(DREG_DREGISTER,0); |
130 | 1846 } |
1847 | |
1848 void | |
1849 code_leave(char *name) | |
1850 { | |
1851 int r1_offsetv; | |
1852 disp&= -size_of_int; | |
1853 r1_offsetv = -disp+max_func_args*size_of_int+code_disp_offset; | |
1854 | |
132 | 1855 fprintf(asi,"L_%d=%d\n",code_disp_label,-r1_offsetv); |
148 | 1856 |
130 | 1857 local_table(); |
1858 free_all_register(); | |
1859 } | |
1860 | |
1861 void | |
1862 enter(char *name) | |
1863 { | |
1864 if (output_mode!=TEXT_EMIT_MODE) | |
1865 text_mode(); | |
1866 else | |
1867 printf("\t.align 2\n"); | |
153 | 1868 /* if (stmode!=STATIC) |
1869 printf(".globl _%s\n",name); */ | |
132 | 1870 printf(".ent %s\n",name); |
130 | 1871 printf("_%s:\n",name); |
132 | 1872 |
130 | 1873 r1_offset_label = fwdlabel(); |
1874 lvar_offset_label = fwdlabel(); | |
152 | 1875 disp_label = fwdlabel(); |
132 | 1876 mask_label = fwdlabel(); |
1877 mask1_label = fwdlabel(); | |
1878 fmask_label = fwdlabel(); | |
1879 fmask1_label = fwdlabel(); | |
152 | 1880 cprestore_label = fwdlabel(); |
132 | 1881 |
1882 printf("\t.frame $fp,L_%d,$31\n",r1_offset_label); | |
1883 printf("\t.mask L_%d,L_%d\n",mask_label,mask1_label); | |
1884 printf("\t.fmask L_%d,L_%d\n",fmask_label,fmask1_label); | |
1885 | |
1886 printf("\t.set noreorder\n"); | |
1887 printf("\t.cpload $25\n"); | |
1888 printf("\t.set reorder\n"); | |
152 | 1889 printf("\tsubu $sp,$sp,L_%d\n",disp_label); |
153 | 1890 printf("\t.cprestore L_%d\n",cprestore_label); |
130 | 1891 max_func_args = 0; |
153 | 1892 max_func_iargs = 0; |
148 | 1893 |
130 | 1894 } |
1895 | |
1896 void | |
1897 enter1() | |
1898 { | |
1899 set_creg(CREG_REGISTER,0); | |
1900 set_freg(FREG_FREGISTER,0); | |
148 | 1901 set_dreg(DREG_DREGISTER,0); |
130 | 1902 } |
1903 | |
153 | 1904 static unsigned int |
1905 code_mask_label() | |
130 | 1906 { |
153 | 1907 int i; |
1908 unsigned int mask=0; | |
1909 for(i=0;i<32;i++) { | |
1910 if (i==28||i==31||(REG_VAR_MIN<=i&&i<=REG_VAR_MIN+max_reg_var)) { | |
1911 mask |= (1<<i); | |
1912 } | |
1913 } | |
1914 return mask; | |
130 | 1915 } |
1916 | |
153 | 1917 static unsigned int |
1918 code_fmask_label() | |
1919 { | |
1920 int i; | |
1921 unsigned int mask=0; | |
1922 for(i=0;i<32;i++) { | |
1923 if (FREG_VAR_MIN<=i&&i<=FREG_VAR_MIN+max_freg_var) { | |
1924 mask |= (1<<i); | |
1925 } | |
1926 } | |
1927 return mask; | |
1928 } | |
1929 | |
1930 | |
130 | 1931 void |
1932 leave(int control, char *name) | |
1933 { | |
131 | 1934 int retcont1=0,sz; |
152 | 1935 int r1_offsetv; |
130 | 1936 |
1937 if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; | |
153 | 1938 reg_save = |
1939 (REAL_MAX_REGISTER-(REG_VAR_BASE-max_reg_var))*size_of_int; | |
1940 freg_save = | |
1941 (REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*size_of_float; | |
130 | 1942 |
1943 if (control) { | |
1944 code_set_return_register(1); | |
1945 } | |
1946 if (retcont) { | |
152 | 1947 /* return from CbC segement */ |
130 | 1948 if (control) jmp(retlabel); |
1949 retcont1 = fwdlabel(); | |
1950 fwddef(retcont); | |
152 | 1951 if (cadr(fnptr->ty)==FLOAT) { |
1952 if (freg!=RET_FREGISTER) | |
1953 printf("\tmov.s %s,%s\n",register_name(RET_FREGISTER), | |
1954 register_name(freg)); | |
1955 } else if (cadr(fnptr->ty)==DOUBLE) { | |
1956 move_dreg(RET_DREGISTER,dreg); | |
130 | 1957 } else if (cadr(fnptr->ty)>0&&( |
1958 car(cadr(fnptr->ty))==STRUCT || | |
1959 car(cadr(fnptr->ty))==UNION)) { | |
1960 sz = size(cadr(fnptr->ty)); | |
152 | 1961 printf("\tli $4,%d\n",sz); |
1962 printf("\tsubl $5,$4,$fp\n"); | |
1963 printf("\tlw $3,(%d)($fp)\n",(my_func_args-1)*size_of_int); | |
130 | 1964 emit_copy(6,3,sz,0,1,1); |
1965 } else if (cadr(fnptr->ty)!=VOID) { | |
152 | 1966 if (creg!=RET_REGISTER) |
1967 printf("\tmove $3,%s\n",register_name(creg)); | |
130 | 1968 } |
152 | 1969 printf("\tj L_%d\n",retcont1); |
130 | 1970 } |
1971 fwddef(retlabel); | |
1972 if (retcont) { | |
1973 fwddef(retcont1); | |
1974 } | |
1975 if (max_freg_var>=0) { | |
1976 } else { | |
1977 } | |
152 | 1978 fprintf(asi,"L_%d=%d\n",r1_offset_label,0); |
1979 fprintf(asi,"L_%d=%d\n",lvar_offset_label,0); | |
153 | 1980 fprintf(asi,"L_%d=0x%x\n",mask_label,code_mask_label()); |
152 | 1981 fprintf(asi,"L_%d=%d\n",mask1_label,0); |
153 | 1982 fprintf(asi,"L_%d=0x%x\n",fmask_label ,code_fmask_label()); |
152 | 1983 fprintf(asi,"L_%d=%d\n",fmask1_label,0); |
153 | 1984 fprintf(asi,"L_%d=%d\n",cprestore_label ,max_func_iargs); |
130 | 1985 |
1986 disp &= -size_of_int; | |
152 | 1987 r1_offsetv = 0; |
1988 | |
1989 printf("\tmove $sp,$fp\n"); | |
1990 printf("\tlw $31,%d($sp)\n",-disp); | |
1991 printf("\tlw $fp,%d($sp)\n",-disp-4); | |
1992 printf("\taddu $sp,$sp,%d\n",r1_offsetv); | |
1993 printf("\tj $31\n"); | |
1994 printf("\t.end print\n"); | |
1995 | |
1996 fprintf(asi,"L_%d=%d\n",disp_label,-r1_offsetv); | |
130 | 1997 |
1998 code_offset_set(); | |
1999 local_table(); | |
2000 labelno++; | |
2001 free_all_register(); | |
2002 } | |
2003 | |
2004 | |
2005 void | |
2006 code_set_return_register(int mode) { | |
148 | 2007 if (cadr(fnptr->ty)==DOUBLE) { |
2008 set_dreg(RET_DREGISTER,mode); | |
2009 } else if (cadr(fnptr->ty)==FLOAT) { | |
130 | 2010 set_freg(RET_FREGISTER,mode); |
148 | 2011 } else if (cadr(fnptr->ty)==VOID) { |
130 | 2012 } else { |
2013 set_creg(RET_REGISTER,mode); | |
2014 } | |
2015 } | |
2016 | |
189 | 2017 int |
2018 code_get_fixed_creg(int reg,int type) { | |
2019 return creg; | |
2020 } | |
2021 | |
130 | 2022 void |
189 | 2023 code_set_fixed_creg(int reg,int mode,int type) { |
148 | 2024 if (type==FLOAT) { |
189 | 2025 set_freg(reg,mode); |
148 | 2026 } else if (type==DOUBLE) { |
189 | 2027 set_dreg(reg,mode); |
130 | 2028 } else { |
189 | 2029 set_creg(reg,mode); |
130 | 2030 } |
2031 } | |
2032 | |
189 | 2033 |
130 | 2034 void |
2035 gen_gdecl(char *n, int gpc) | |
2036 { | |
2037 if (stmode!=STATIC) | |
153 | 2038 printf("\t.globl _%s\n",n); |
130 | 2039 } |
2040 | |
2041 void | |
2042 align(int t) | |
2043 { | |
2044 if (t!=CHAR) { | |
2045 if (data_alignment & 1) | |
2046 printf("\t.align 2\n"); | |
2047 data_alignment = 0; | |
2048 } | |
2049 } | |
2050 | |
2051 void | |
2052 emit_data(int e, int t, NMTBL *n) | |
2053 { | |
2054 int l; | |
195 | 2055 #if FLOAT_CODE |
130 | 2056 double d; |
2057 float f; | |
195 | 2058 #endif |
130 | 2059 char *name; |
2060 name = n->nm; | |
156 | 2061 if(mode!=GDECL&&mode!=STADECL) { |
130 | 2062 error(-1); return; |
2063 } | |
2064 if (chk) return; | |
2065 if (n->dsp != -1) { | |
2066 n->dsp = -1; /* initiallized flag */ | |
153 | 2067 /* printf(".globl\t_%s\n",name); */ |
130 | 2068 data_mode(name); |
2069 align(t); | |
2070 printf("_%s:\n",name); | |
2071 } else { | |
2072 data_mode(0); | |
2073 } | |
2074 if(car(e)==CONST) { | |
168 | 2075 if (t==CHAR||t==UCHAR) { |
130 | 2076 printf("\t.byte %d\n",cadr(e)); |
2077 if (data_alignment>0) | |
2078 data_alignment++; | |
2079 gpc += 1; | |
168 | 2080 } else if (t==SHORT||t==USHORT) { |
2081 printf("\t.short %d\n",cadr(e)); | |
130 | 2082 if (data_alignment>0) data_alignment++; |
2083 gpc += 2; | |
2084 } else { | |
148 | 2085 printf("\t.word %d\n",cadr(e)); |
130 | 2086 gpc += size_of_int; |
2087 } | |
195 | 2088 #if FLOAT_CODE |
130 | 2089 } else if(t==DOUBLE) { |
148 | 2090 d = dcadr(e); |
153 | 2091 printf("\t.word\t0x%x\n\t.word\t0x%x\n",code_d1(d),code_d2(d)); |
130 | 2092 } else if(t==FLOAT) { |
148 | 2093 f = dcadr(e); |
2094 printf("\t.word\t0x%x\n",*(int *)&f); | |
195 | 2095 #endif |
130 | 2096 } else if(t!=CHAR) { |
2097 gpc += size_of_int; | |
148 | 2098 if(car(e)==ADDRESS&&car(cadr(e))==GVAR) { |
2099 printf("\t.word _%s\n",((NMTBL *)cadr(cadr(e)))->nm); | |
2100 } else if(car(e)==FNAME) { | |
2101 printf("\t.word _%s\n",((NMTBL *)cadr(e))->nm); | |
2102 } else if(car(e)==GVAR) { | |
2103 printf("\t.word _%s\n",((NMTBL *)cadr(e))->nm); | |
2104 } else if(car(e)==STRING) { | |
2105 if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) { | |
2106 l = fwdlabel(); | |
2107 printf("\t.word L_%d\n",l); | |
2108 printf(".rdata\n\t.align 2\n"); | |
2109 printf("L_%d:\n",l); | |
2110 output_mode = RODATA_EMIT_MODE; | |
2111 } | |
2112 ascii((char *)cadr(e)); | |
130 | 2113 } else error(TYERR); |
168 | 2114 } else error(TYERR); |
130 | 2115 } |
2116 | |
2117 void | |
2118 emit_data_closing(NMTBL *n) | |
2119 { | |
2120 #ifdef DOT_SIZE | |
2121 int lb; | |
2122 #endif | |
2123 if (chk) return; | |
2124 if (mode==GDECL) { | |
2125 data_mode(0); | |
2126 #ifdef DOT_SIZE | |
2127 lb=fwdlabel(); | |
2128 printf("L_%d:\n",lb); | |
2129 printf("\t.size\t%s,L_%d-%s\n",n->nm,lb,n->nm); | |
2130 #endif | |
2131 } | |
2132 } | |
2133 | |
149 | 2134 void |
130 | 2135 global_table(void) |
2136 { | |
2137 NMTBL *n; | |
131 | 2138 int init; |
130 | 2139 init=0; |
2140 for(n=ntable;n < &ntable[GSYMS];n++) { | |
148 | 2141 if ((n->sc == GVAR) && n->dsp != -1) { |
2142 /* n->dsp = -1 means initialized global */ | |
2143 if (init==0) { | |
2144 data_mode(0); | |
2145 init=1; | |
2146 } | |
2147 printf(".comm _%s,%d\n",n->nm,size(n->ty)); | |
2148 } else if ((n->sc==STATIC) && n->dsp != -1) { | |
2149 /* n->dsp = -1 means initialized global */ | |
2150 if (init==0) { | |
2151 data_mode(0); | |
2152 init=1; | |
2153 } | |
2154 printf(".lcomm _%s,%d\n",n->nm,size(n->ty)); | |
2155 } | |
130 | 2156 } |
2157 } | |
2158 | |
2159 void | |
2160 local_table(void) | |
2161 { | |
2162 NMTBL *n; | |
2163 int init; | |
2164 init=0; | |
2165 /* static local variables */ | |
2166 for(n=ntable+GSYMS;n < &ntable[GSYMS+LSYMS];n++) { | |
2167 if (n->sc == GVAR) { | |
2168 if (init==0) { | |
2169 data_mode(0); | |
2170 init=1; | |
2171 } | |
156 | 2172 if (n->dsp!=-1) /* n->dsp = -1 means initialized global */ |
130 | 2173 printf(".lcomm _%s,%d\n",n->nm,size(n->ty)); |
2174 } | |
2175 } | |
2176 } | |
2177 | |
2178 void | |
2179 text_mode(void) | |
2180 { | |
2181 if (output_mode!=TEXT_EMIT_MODE) { | |
2182 printf(".text\n"); | |
2183 printf("\t.align 2\n"); | |
2184 output_mode = TEXT_EMIT_MODE; | |
2185 } | |
2186 } | |
2187 | |
2188 void | |
2189 data_mode(char *name) | |
2190 { | |
2191 if (output_mode!=DATA_EMIT_MODE) { | |
2192 printf(".data\n"); | |
2193 output_mode = DATA_EMIT_MODE; | |
2194 } | |
2195 if (name) | |
2196 printf("\t.type\t%s,@object\n",name); | |
2197 } | |
2198 | |
195 | 2199 #if FLOAT_CODE |
2200 | |
130 | 2201 char * |
2202 fstore(int d) | |
2203 { | |
148 | 2204 return (d?"stfd":"stfs"); |
130 | 2205 } |
2206 | |
2207 char * | |
2208 fload(int d) | |
2209 { | |
148 | 2210 return d?"lfd":"lfs"; |
130 | 2211 } |
2212 | |
153 | 2213 static |
2214 void code_dpfunc(char *f) | |
2215 { | |
2216 if (max_func_iargs<16) max_func_iargs=16; | |
2217 printf("\tjal %s\n",f); | |
2218 } | |
2219 | |
130 | 2220 void |
138 | 2221 code_cmp_dregister(int e2,int d) |
130 | 2222 { |
149 | 2223 char *frn,*grn; |
2224 int greg; | |
2225 | |
2226 if (d) { | |
2227 printf("\tli.d $6,%g\n",0.0); | |
2228 code_save_stacks(); | |
2229 move_dreg(4+DREG_OFFSET,freg); | |
153 | 2230 code_dpfunc("dpcmp"); |
2231 if (max_func_iargs<16) max_func_iargs=16; | |
149 | 2232 set_dreg(RET_DREGISTER,0); |
2233 return; | |
2234 } else { | |
2235 grn = register_name(greg = get_dregister(d)); | |
2236 frn = register_name(e2); | |
2237 printf("\tli.s %s,%g\n",grn,0.0); | |
2238 printf("\tc.eq.s %s,%s\n",grn,frn); | |
2239 free_register(greg); | |
2240 return; | |
2241 } | |
130 | 2242 } |
2243 | |
2244 void | |
138 | 2245 code_dregister(int e2,int freg,int d) |
130 | 2246 { |
141 | 2247 if (freg!=e2) { |
149 | 2248 if (d) { |
2249 if (!is_double_reg(e2)) error(-1); | |
2250 move_dreg(freg,e2); | |
2251 } else { | |
2252 if (!is_float_reg(e2)) error(-1); | |
2253 printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2)); | |
2254 } | |
141 | 2255 } |
130 | 2256 } |
2257 | |
2258 void code_dassign_gvar(int e2,int freg,int d) | |
2259 { | |
149 | 2260 NMTBL *n = (NMTBL*)cadr(e2); |
2261 if (d) { | |
2262 if (!is_double_reg(freg)) error(-1); | |
2263 printf("\tsw %s,0(%s)\n",dregister_name0(freg),n->nm); | |
2264 printf("\tsw %s,0(%s)\n",dregister_name1(freg),n->nm); | |
2265 } else { | |
2266 printf("\ts.s %s,0(%s)\n",fregister_name(freg),n->nm); | |
2267 } | |
130 | 2268 } |
2269 | |
2270 void code_dassign_lvar(int e2,int freg,int d) | |
2271 { | |
149 | 2272 if (d) { |
2273 if (!is_double_reg(freg)) error(-1); | |
2274 printf("\tsw %s,",dregister_name0(freg)); | |
2275 lvar(e2); | |
2276 printf("\tsw %s,",dregister_name1(freg)); | |
2277 e2 += size_of_double/2; | |
2278 } else { | |
2279 printf("\ts.s %s,",fregister_name(freg)); | |
2280 } | |
130 | 2281 lvar(e2); |
2282 } | |
2283 | |
2284 void code_dassign(int e2,int freg,int d) | |
2285 { | |
149 | 2286 if (d) { |
2287 if (!is_double_reg(freg)) error(-1); | |
2288 printf("\tsw %s,0(%s)\n",dregister_name0(freg),register_name(e2)); | |
2289 printf("\tsw %s,4(%s)\n",dregister_name1(freg),register_name(e2)); | |
2290 } else { | |
2291 printf("\ts.s %s,0(%s)\n",fregister_name(freg),register_name(e2)); | |
2292 } | |
130 | 2293 } |
2294 | |
2295 void | |
138 | 2296 code_dassign_dregister(int e2,int d,int freg) { |
149 | 2297 /* これってさ、code_dregister と同じ? */ |
141 | 2298 if (e2!=freg) { |
149 | 2299 if (d) { |
2300 if (!is_double_reg(freg)) error(-1); | |
2301 move_dreg(freg,e2); | |
2302 } else { | |
2303 printf("\tmov.s %s,%s\n",fregister_name(e2),fregister_name(freg)); | |
2304 } | |
141 | 2305 } |
149 | 2306 |
130 | 2307 } |
2308 | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2309 static double d0 = 1.0; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2310 |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2311 int |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2312 code_d1(double d) |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2313 { |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2314 int *i = (int *)&d0; int *j = (int *)&d; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2315 return (i[1] == 0x3ff00000)?j[0]:j[1]; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2316 } |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2317 |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2318 int |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2319 code_d2(double d) |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2320 { |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2321 int *i = (int *)&d0; int *j = (int *)&d; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2322 return (i[1] == 0x3ff00000)?j[1]:j[0]; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2323 } |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2324 |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2325 int |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2326 code_f(double d) |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2327 { |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2328 float f = d; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2329 int *j = (int *)&f; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2330 return *j; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2331 } |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2332 |
148 | 2333 void |
2334 code_dconst(int e2,int freg,int d) | |
130 | 2335 { |
138 | 2336 double value = dcadr(e2); |
149 | 2337 char *frn; |
2338 if (d) { | |
2339 printf("\tli.d %s,%g\n",dregister_name0(freg),value); | |
2340 } else { | |
2341 frn = fregister_name(freg); | |
2342 printf("\tli.s %s,%g\n",frn,value); | |
148 | 2343 } |
130 | 2344 } |
2345 | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2346 |
138 | 2347 void code_dneg(int freg,int d) |
130 | 2348 { |
149 | 2349 char *frn; |
2350 if (d) { | |
2351 code_save_stacks(); | |
2352 move_dreg(4+DREG_OFFSET,freg); | |
153 | 2353 code_dpfunc("dpneg"); |
149 | 2354 set_dreg(RET_DREGISTER,0); |
2355 } else { | |
2356 frn = fregister_name(freg); | |
2357 printf("\tfneg %s,%s\n",frn,frn); | |
2358 } | |
130 | 2359 } |
2360 | |
148 | 2361 void code_d2i(int freg0) |
130 | 2362 { |
149 | 2363 code_save_stacks(); |
2364 set_dreg(RET_DREGISTER,1); | |
153 | 2365 code_dpfunc("dptoli"); |
149 | 2366 set_creg(RET_REGISTER,0); |
130 | 2367 } |
2368 | |
148 | 2369 void code_i2d(int creg0) |
2370 { | |
141 | 2371 code_save_stacks(); |
148 | 2372 set_creg(RET_REGISTER,1); |
153 | 2373 code_dpfunc("litodp"); |
150 | 2374 set_dreg(RET_DREGISTER,0); |
141 | 2375 } |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2376 |
148 | 2377 void code_d2u(int freg0) |
2378 { | |
141 | 2379 code_save_stacks(); |
149 | 2380 set_dreg(RET_DREGISTER,1); |
153 | 2381 code_dpfunc("dptoul"); |
148 | 2382 set_creg(RET_REGISTER,0); |
141 | 2383 } |
2384 | |
148 | 2385 void code_u2d(int creg0) |
2386 { | |
2387 code_save_stacks(); | |
2388 set_creg(RET_REGISTER,1); | |
153 | 2389 code_dpfunc("ultodp"); |
149 | 2390 set_dreg(RET_DREGISTER,0); |
141 | 2391 } |
2392 | |
149 | 2393 void code_d2f(int freg) { |
2394 code_save_stacks(); | |
2395 set_dreg(RET_DREGISTER,1); | |
153 | 2396 code_dpfunc("dptofp"); |
149 | 2397 set_freg(RET_FREGISTER,0); |
2398 } | |
2399 | |
2400 void code_f2d(int freg) { | |
2401 code_save_stacks(); | |
2402 set_freg(RET_FREGISTER,1); | |
153 | 2403 code_dpfunc("fptodp"); |
149 | 2404 set_dreg(RET_DREGISTER,0); |
2405 } | |
2406 | |
2407 void code_f2i(int freg) { | |
2408 printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg), | |
2409 register_name(freg),register_name(ireg)); | |
2410 creg = ireg; | |
2411 } | |
2412 | |
2413 void code_f2u(int freg) { | |
2414 printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg), | |
2415 register_name(freg),register_name(ireg)); | |
2416 creg = ireg; | |
2417 } | |
2418 | |
2419 void code_i2f(int creg0) { | |
2420 printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg)); | |
2421 creg = freg; | |
2422 } | |
2423 | |
2424 void code_u2f(int creg0) { | |
2425 printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg)); | |
2426 creg = freg; | |
2427 } | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2428 |
130 | 2429 void code_drgvar(int e2,int d,int freg) |
2430 { | |
151 | 2431 char *name = ((NMTBL*)cadr(e2))->nm; |
149 | 2432 if (d) { |
151 | 2433 printf("\tlw %s,%s\n",dregister_name0(freg),name); |
2434 printf("\tlw %s,%s\n",dregister_name1(freg),name); | |
149 | 2435 } else { |
151 | 2436 printf("\tl.s %s,%s\n",fregister_name(freg),name); |
149 | 2437 } |
130 | 2438 } |
2439 | |
2440 | |
2441 void code_drlvar(int e2,int d,int freg) | |
2442 { | |
149 | 2443 if (d) { |
152 | 2444 printf("\tlw %s,",dregister_name0(freg)); lvar(e2); |
2445 printf("\tlw %s,",dregister_name1(freg)); lvar(e2+size_of_double/2); | |
149 | 2446 } else { |
2447 printf("\tl.s %s,",fregister_name(freg)); lvar(e2); | |
2448 } | |
130 | 2449 } |
2450 | |
138 | 2451 void code_cmp_drgvar(int e2,int d) |
130 | 2452 { |
149 | 2453 char *frn; |
2454 int g; | |
2455 if (d) { | |
2456 code_save_stacks(); | |
2457 set_dreg(RET_DREGISTER,1); | |
2458 code_drgvar(e2,d,RET_DREGISTER+2); | |
153 | 2459 code_dpfunc("dcmp"); |
149 | 2460 } else { |
2461 frn=fregister_name(freg); | |
2462 g=get_dregister(d); | |
2463 code_drgvar(e2,d,g); | |
2464 printf("\tfc.eq.s %s,%s\n",frn,fregister_name(g)); | |
2465 free_register(g); | |
2466 } | |
130 | 2467 } |
2468 | |
138 | 2469 void code_cmp_drlvar(int e2,int d) |
130 | 2470 { |
2471 char *frn=fregister_name(freg); | |
149 | 2472 int g; |
2473 if (d) { | |
2474 code_save_stacks(); | |
2475 set_dreg(RET_DREGISTER,1); | |
2476 code_drgvar(e2,d,RET_DREGISTER+2); | |
153 | 2477 code_dpfunc("dcmp"); |
149 | 2478 } else { |
2479 g=get_dregister(d); | |
2480 code_drlvar(e2,d,g); | |
2481 printf("\tc.eq.s %s,%s\n",frn,fregister_name(g)); | |
2482 free_register(g); | |
2483 } | |
2484 } | |
130 | 2485 |
149 | 2486 static void |
2487 dtosop0(char *opn,int e1,int d,int cmp) | |
2488 { | |
2489 char *frn; | |
2490 char *grn; | |
2491 if (d) { | |
2492 code_save_stacks(); | |
2493 set_dreg(RET_DREGISTER,1); | |
2494 move_dreg(RET_DREGISTER+2,e1); | |
153 | 2495 code_dpfunc(opn); |
149 | 2496 } else { |
2497 frn=fregister_name(freg); | |
2498 grn=fregister_name(e1); | |
2499 if (cmp) { | |
2500 printf("\t%s %s,%s\n",opn,frn,grn); | |
2501 } else { | |
2502 printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); | |
2503 } | |
2504 } | |
2505 free_register(e1); | |
141 | 2506 } |
2507 | |
149 | 2508 |
130 | 2509 void dtosop(int op,int e1) |
2510 { | |
2511 switch(op) { | |
149 | 2512 case FADD: dtosop0("fadd",e1,0,0); return; |
2513 case DADD: dtosop0("dpadd",e1,1,0); return; | |
2514 case FSUB: dtosop0("fadd",e1,0,0); return; | |
2515 case DSUB: dtosop0("dpsub",e1,1,0); return; | |
2516 case FDIV: dtosop0("fadd",e1,0,0); return; | |
2517 case DDIV: dtosop0("dpdiv",e1,1,0); return; | |
2518 case FMUL: dtosop0("fadd",e1,0,0); return; | |
2519 case DMUL: dtosop0("dpmul",e1,1,0); return; | |
141 | 2520 case DCMPGE: |
149 | 2521 case DCMP: dtosop0("dpcmp",e1,1,1); return; |
2522 case FCMPGE: dtosop0("c.le.s",e1,0,1); return; | |
2523 case FCMP: dtosop0("c.eq.s",e1,0,1); return; | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2524 default: |
149 | 2525 error(-1); return; |
130 | 2526 } |
2527 } | |
2528 | |
2529 void | |
2530 code_dassop(int op,int d) { | |
2531 /* we have lvalue in creg, applied floating value is in freg */ | |
149 | 2532 char *frn; |
2533 int xreg; | |
130 | 2534 char *crn=register_name(creg); |
2535 | |
149 | 2536 if (d) { |
2537 xreg=emit_dpop(d); | |
2538 printf("\tlw %s,0(%s)\n",dregister_name0(freg),crn); | |
2539 printf("\tlw %s,%d(%s)\n",dregister_name1(freg),size_of_int,crn); | |
2540 dtosop(op,xreg); | |
2541 printf("\tsw %s,0(%s)\n",dregister_name0(freg),crn); | |
2542 printf("\tsw %s,%d(%s)\n",dregister_name1(freg),size_of_int,crn); | |
2543 emit_dpop_free(xreg,d); | |
2544 creg = dreg; | |
2545 } else { | |
2546 xreg=emit_dpop(d); | |
2547 frn=fregister_name(freg); | |
2548 crn=register_name(creg); | |
2549 | |
2550 printf("\tl.s %s,0(%s)\n",frn,crn); | |
2551 dtosop(op,xreg); | |
2552 printf("\ts.s %s,0(%s)\n",frn,crn); | |
2553 emit_dpop_free(xreg,d); | |
2554 creg = freg; | |
2555 } | |
130 | 2556 } |
2557 | |
219 | 2558 void |
2559 code_register_dassop(int reg,int op,int d) { | |
2560 error(-1); | |
2561 } | |
2562 | |
130 | 2563 |
2564 void | |
2565 code_dpreinc(int e1,int e2,int d,int reg) { | |
2566 char *frn; | |
2567 char *crn; | |
2568 int g; | |
149 | 2569 char *grn; |
130 | 2570 |
2571 g_expr(e2); | |
2572 | |
149 | 2573 if (d) { |
2574 crn=register_name(creg); | |
2575 frn=fregister_name(freg); | |
130 | 2576 |
149 | 2577 code_save_stacks(); |
2578 set_dreg(RET_DREGISTER,0); | |
2579 printf("\tlw $4,0(%s)\n",crn); | |
2580 printf("\tlw $5,%d(%s)\n",size_of_int,crn); | |
2581 printf("\tli.d $6,1.0\n"); | |
2582 if (caddr(e1)>0) | |
153 | 2583 code_dpfunc("dpadd"); |
149 | 2584 else |
153 | 2585 code_dpfunc("dpsub"); |
149 | 2586 printf("\tsw $2,0(%s)\n",crn); |
2587 printf("\tsw $3,%d(%s)\n",size_of_int,crn); | |
2588 creg = dreg; | |
2589 } else { | |
2590 crn=register_name(creg); | |
2591 frn=fregister_name(freg); | |
2592 grn=fregister_name(g=get_dregister(d)); | |
2593 | |
2594 printf("\tl.s %s,0(%s)\n",frn,crn); | |
2595 printf("\tli.s %s,1.0\n",grn); | |
2596 if (caddr(e1)>0) | |
2597 printf("\tfadd %s,%s,%s\n",frn,frn,grn); | |
2598 else | |
2599 printf("\tfsub %s,%s,%s\n",frn,frn,grn); | |
2600 printf("\ts.s %s,0(%s)\n",frn,crn); | |
2601 free_register(g); | |
2602 creg = freg; | |
2603 } | |
130 | 2604 } |
2605 | |
2606 void | |
2607 code_dpostinc(int e1,int e2,int d,int reg) { | |
2608 char *frn; | |
2609 char *crn; | |
2610 int g; | |
149 | 2611 char *grn; |
130 | 2612 |
2613 g_expr(e2); | |
2614 | |
149 | 2615 if (d) { |
2616 crn=register_name(creg); | |
2617 g = get_dregister(d); | |
2618 set_dreg(RET_DREGISTER,0); | |
2619 printf("\tlw $4,0(%s)\n",crn); | |
2620 printf("\tlw $5,%d(%s)\n",size_of_int,crn); | |
2621 move_dreg(g,4+DREG_OFFSET); | |
2622 printf("\tli.d $6,1.0\n"); | |
2623 if (caddr(e1)>0) | |
153 | 2624 code_dpfunc("dpadd"); |
149 | 2625 else |
153 | 2626 code_dpfunc("dpsub"); |
149 | 2627 set_dreg(RET_DREGISTER,0); |
2628 printf("\tsw $2,0(%s)\n",crn); | |
2629 printf("\tsw $3,%d(%s)\n",size_of_int,crn); | |
152 | 2630 free_register(dreg); |
149 | 2631 set_dreg(g,0); |
2632 creg = g; | |
2633 } else { | |
2634 crn=register_name(creg); | |
2635 frn=fregister_name(freg); | |
2636 grn=fregister_name(g=get_dregister(d)); | |
130 | 2637 |
149 | 2638 printf("\tl.s %s,0(%s)\n",frn,crn); |
2639 printf("\tli.s %s,1.0\n",grn); | |
2640 if (caddr(e1)>0) | |
2641 printf("\tfadd %s,%s,%s\n",frn,frn,grn); | |
2642 else | |
2643 printf("\tfsub %s,%s,%s\n",frn,frn,grn); | |
2644 printf("\ts.s %s,0(%s)\n",grn,crn); | |
2645 free_register(g); | |
2646 creg = freg; | |
2647 } | |
2648 | |
130 | 2649 } |
2650 | |
2651 void | |
2652 drexpr(int e1, int e2,int l1, int op) | |
2653 { | |
149 | 2654 g_expr(list3(((op==FOP+EQ||op==FOP+NEQ)?DCMP:FCMPGE),e1,e2)); |
130 | 2655 switch(op) { |
149 | 2656 case DOP+GE: |
2657 printf("\tbgez\tL_%d\n",l1); | |
2658 break; | |
2659 case DOP+GT: | |
2660 printf("\tbltz\tL_%d\n",l1); | |
2661 break; | |
2662 case DOP+EQ: | |
2663 printf("\tbeq\tL_%d\n",l1); | |
2664 break; | |
2665 case DOP+NEQ: | |
2666 printf("\tbne\tL_%d\n",l1); | |
2667 break; | |
2668 case FOP+GE: | |
2669 printf("\tbc1tl\tL_%d\n",l1); | |
2670 break; | |
2671 case FOP+GT: | |
2672 printf("\tbc1tl\tL_%d\n",l1); | |
2673 break; | |
2674 case FOP+EQ: | |
2675 printf("\tbc1f\tL_%d\n",l1); | |
2676 break; | |
2677 case FOP+NEQ: | |
2678 printf("\tbc1f\tL_%d\n",l1); | |
2679 break; | |
130 | 2680 } |
2681 } | |
2682 | |
138 | 2683 int emit_dpop(int d) |
130 | 2684 { |
2685 int xreg,reg; | |
151 | 2686 if (d) |
2687 xreg=pop_dregister(); | |
2688 else | |
2689 xreg=pop_fregister(); | |
130 | 2690 if (xreg<= -REG_LVAR_OFFSET) { |
138 | 2691 reg = get_dregister(d); |
149 | 2692 code_drlvar(REG_LVAR_OFFSET+xreg,d,reg); |
130 | 2693 free_lvar(REG_LVAR_OFFSET+xreg); |
205 | 2694 xreg=reg; |
130 | 2695 } |
2696 return xreg; | |
2697 } | |
2698 | |
138 | 2699 void emit_dpop_free(int e1,int d) |
130 | 2700 { |
148 | 2701 free_register(e1); |
130 | 2702 } |
2703 | |
133 | 2704 void emit_dpush(int d) |
130 | 2705 { |
2706 int new_reg; | |
2707 if (freg_sp>MAX_MAX) error(-1); | |
149 | 2708 new_reg = get_dregister(d); |
151 | 2709 if (d) { |
2710 dreg_stack[dreg_sp++] = dreg; /* push するかわりにレジスタを使う */ | |
2711 creg = dreg = new_reg; | |
2712 } else { | |
2713 freg_stack[freg_sp++] = freg; /* push するかわりにレジスタを使う */ | |
2714 creg = freg = new_reg; | |
2715 } | |
130 | 2716 } |
2717 | |
195 | 2718 #endif |
2719 | |
130 | 2720 void |
2721 code_save_stacks() | |
2722 { | |
2723 int i,reg; | |
2724 for(i=0;i<reg_sp;i++) { | |
2725 if ((reg=reg_stack[i])>=0) { | |
2726 code_assign_lvar( | |
2727 (reg_stack[i]=new_lvar(size_of_int)),reg,0); | |
2728 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; | |
2729 } | |
2730 } | |
195 | 2731 #if FLOAT_CODE |
149 | 2732 for(i=0;i<dreg_sp;i++) { |
2733 if ((reg=dreg_stack[i])>=0) { | |
2734 code_dassign_lvar( | |
2735 (dreg_stack[i]=new_lvar(size_of_double)),reg,1); | |
2736 dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET; | |
2737 } | |
2738 } | |
130 | 2739 for(i=0;i<freg_sp;i++) { |
2740 if ((reg=freg_stack[i])>=0) { | |
2741 code_dassign_lvar( | |
149 | 2742 (freg_stack[i]=new_lvar(size_of_float)),reg,0); |
130 | 2743 freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; |
2744 } | |
2745 } | |
195 | 2746 #endif |
130 | 2747 } |
2748 | |
2749 void | |
2750 emit_lib(char *p[]) | |
2751 { | |
2752 while(*p) { | |
2753 printf("%s\n",*p++); | |
2754 } | |
2755 } | |
2756 | |
2757 void | |
2758 code_closing() | |
2759 { | |
2760 global_table(); | |
2761 /* printf("\t.ident \"Micro-C compiled\"\n"); */ | |
149 | 2762 fclose(asi); |
130 | 2763 } |
2764 | |
195 | 2765 |
2766 #if LONGLONG_CODE | |
2767 | |
2768 | |
2769 /* 64bit int part */ | |
2770 | |
2771 void lrexpr(int e1, int e2,int l1, int op) | |
2772 { | |
2773 } | |
2774 | |
2775 int lpop_register() | |
2776 { | |
2777 return 0; | |
2778 } | |
2779 | |
2780 int emit_lpop() | |
2781 { | |
2782 return 0; | |
2783 } | |
2784 | |
2785 void code_lregister(int e2,int reg) | |
2786 { | |
2787 | |
2788 } | |
2789 | |
2790 void code_cmp_lregister(int reg) | |
2791 { | |
2792 | |
2793 } | |
2794 | |
2795 void code_cmp_lrgvar(int e1,int e2) | |
2796 { | |
2797 | |
2798 } | |
2799 | |
2800 void code_cmp_lrlvar(int e1,int e2) | |
2801 { | |
2802 | |
2803 } | |
2804 | |
2805 void code_lassign(int e1,int e2) | |
2806 { | |
2807 | |
2808 } | |
2809 | |
2810 void code_lassign_gvar(int e1,int e2) | |
2811 { | |
2812 | |
2813 } | |
2814 | |
2815 void code_lassign_lvar(int e1,int e2) | |
2816 { | |
2817 | |
2818 } | |
2819 | |
2820 void code_lassign_lregister(int e2,int reg) | |
2821 { | |
2822 | |
2823 } | |
2824 | |
2825 void code_lconst(int e1,int e2) | |
2826 { | |
2827 | |
2828 } | |
2829 | |
212 | 2830 void code_lneg(int e1) |
195 | 2831 { |
2832 | |
2833 } | |
2834 | |
2835 void code_lrgvar(int e1,int e2) | |
2836 { | |
2837 | |
2838 } | |
2839 | |
2840 void code_lrlvar(int e1,int e2) | |
2841 { | |
2842 | |
2843 } | |
2844 | |
2845 void ltosop(int e1,int e2) | |
2846 { | |
2847 | |
2848 } | |
2849 | |
213 | 2850 int code_lconst_op_p(int op,int e) {return 0;} |
2851 void loprtc(int op,int e) {} | |
2852 | |
195 | 2853 void emit_lpop_free(int e1) |
2854 { | |
2855 | |
2856 } | |
2857 | |
2858 void emit_lpush() | |
2859 { | |
2860 | |
2861 } | |
2862 | |
2863 void code_i2ll(int creg) | |
2864 { | |
2865 | |
2866 } | |
2867 | |
2868 void code_i2ull(int creg) | |
2869 { | |
2870 | |
2871 } | |
2872 | |
2873 void code_u2ll(int creg) | |
2874 { | |
2875 | |
2876 } | |
2877 | |
2878 void code_u2ull(int creg) | |
2879 { | |
2880 | |
2881 } | |
2882 | |
2883 void code_ll2i(int creg) | |
2884 { | |
2885 | |
2886 } | |
2887 | |
2888 void code_ll2u(int creg) | |
2889 { | |
2890 | |
2891 } | |
2892 | |
2893 void code_ull2i(int creg) | |
2894 { | |
2895 | |
2896 } | |
2897 | |
2898 void code_ull2u(int creg) | |
2899 { | |
2900 | |
2901 } | |
2902 | |
2903 #if FLOAT_CODE | |
2904 void code_d2ll(int creg) | |
2905 { | |
2906 | |
2907 } | |
2908 | |
2909 void code_d2ull(int creg) | |
2910 { | |
2911 | |
2912 } | |
2913 | |
2914 void code_f2ll(int creg) | |
2915 { | |
2916 | |
2917 } | |
2918 | |
2919 void code_f2ull(int creg) | |
2920 { | |
2921 | |
2922 } | |
2923 | |
2924 void code_ll2d(int creg) | |
2925 { | |
2926 | |
2927 } | |
2928 | |
2929 void code_ll2f(int creg) | |
2930 { | |
2931 | |
2932 } | |
2933 | |
2934 void code_ull2d(int creg) | |
2935 { | |
2936 | |
2937 } | |
2938 | |
2939 void code_ull2f(int creg) | |
2940 { | |
2941 | |
2942 } | |
2943 | |
2944 void code_ull2ll(int creg) | |
2945 { | |
2946 | |
2947 } | |
2948 | |
2949 void code_ull2ull(int creg) | |
2950 { | |
2951 | |
2952 } | |
2953 | |
2954 #endif | |
2955 | |
2956 | |
2957 void code_lpreinc(int e1,int e2,int reg) | |
2958 { | |
2959 | |
2960 } | |
2961 | |
2962 void code_lpostinc(int e1,int e2,int reg) | |
2963 { | |
2964 | |
2965 } | |
2966 | |
2967 void code_lassop(int op) | |
2968 { | |
2969 | |
2970 } | |
2971 | |
219 | 2972 void |
2973 code_register_lassop(int reg,int op) { | |
2974 } | |
2975 | |
2976 | |
195 | 2977 |
2978 #endif | |
2979 | |
130 | 2980 /* end */ |
2981 |