Mercurial > hg > CbC > old > device
comparison mc-code-spu.c @ 880:5313ed059cee
no tabs in source
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 03 Apr 2014 10:43:01 +0900 |
parents | c0ad9d810b6c |
children | 8bdd5061cb8f |
comparison
equal
deleted
inserted
replaced
879:528595192871 | 880:5313ed059cee |
---|---|
26 #include "mc-code.h" | 26 #include "mc-code.h" |
27 #include "mc-codegen.h" | 27 #include "mc-codegen.h" |
28 | 28 |
29 char *l_include_path[]={ | 29 char *l_include_path[]={ |
30 "/usr/lib/gcc/spu/4.0.2/include", | 30 "/usr/lib/gcc/spu/4.0.2/include", |
31 "/usr/spu/include", | 31 "/usr/spu/include", |
32 0}; | 32 0}; |
33 | 33 |
34 // va_start, va_arg is wrong, use va_arm.h | 34 // va_start, va_arg is wrong, use va_arm.h |
35 | 35 |
36 static char *init_src0 = "\ | 36 static char *init_src0 = "\ |
37 #define __SPU__ 1\n\ | 37 #define __SPU__ 1\n\ |
174 | 174 |
175 static int max_reg_var; | 175 static int max_reg_var; |
176 | 176 |
177 | 177 |
178 static char *reg_name[] = { | 178 static char *reg_name[] = { |
179 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", | 179 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", |
180 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", | 180 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", |
181 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", | 181 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", |
182 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", | 182 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", |
183 "$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39", | 183 "$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39", |
184 "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", | 184 "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", |
185 "$48", "$49", "$50", "$51", "$52", "$53", "$54", "$55", | 185 "$48", "$49", "$50", "$51", "$52", "$53", "$54", "$55", |
186 "$56", "$57", "$58", "$59", "$60", "$61", "$62", "$63", | 186 "$56", "$57", "$58", "$59", "$60", "$61", "$62", "$63", |
187 "$64", "$65", "$66", "$67", "$68", "$69", "$70", "$71", | 187 "$64", "$65", "$66", "$67", "$68", "$69", "$70", "$71", |
188 "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", | 188 "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", |
189 "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", | 189 "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", |
190 "$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95", | 190 "$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95", |
191 "$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103", | 191 "$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103", |
192 "$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111", | 192 "$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111", |
193 "$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119", | 193 "$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119", |
194 "$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127" | 194 "$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127" |
195 }; | 195 }; |
196 | 196 |
197 #define register_name(i) reg_name[i] | 197 #define register_name(i) reg_name[i] |
198 | 198 |
199 char *rn(int i) { return register_name(i); } | 199 char *rn(int i) { return register_name(i); } |
315 int code_f = is_code(fnptr); | 315 int code_f = is_code(fnptr); |
316 | 316 |
317 disp &= -SIZE_OF_INT; | 317 disp &= -SIZE_OF_INT; |
318 | 318 |
319 if (code_f) { | 319 if (code_f) { |
320 r1_offsetv = disp-max_func_args*SIZE_OF_INT+code_disp_offset; | 320 r1_offsetv = disp-max_func_args*SIZE_OF_INT+code_disp_offset; |
321 printf("\t.set .LC%d, %d\n",r1_offset_label,r1_offsetv); | 321 printf("\t.set .LC%d, %d\n",r1_offset_label,r1_offsetv); |
322 } else { | 322 } else { |
323 lvar_offsetv = | 323 lvar_offsetv = |
324 -(-32 - max_reg_var*SIZE_OF_INT-max_reg_var*SIZE_OF_DOUBLE); | 324 -(-32 - max_reg_var*SIZE_OF_INT-max_reg_var*SIZE_OF_DOUBLE); |
325 printf("\t.set .LC%d, %d\n",lvar_offset_label,lvar_offsetv); | 325 printf("\t.set .LC%d, %d\n",lvar_offset_label,lvar_offsetv); |
326 } | 326 } |
327 if (max_func_arg_label) { | 327 if (max_func_arg_label) { |
328 printf("\t.set .LC%d, %d\n",max_func_arg_label,max_func_args*SIZE_OF_INT); | 328 printf("\t.set .LC%d, %d\n",max_func_arg_label,max_func_args*SIZE_OF_INT); |
329 max_func_arg_label = 0; | 329 max_func_arg_label = 0; |
330 } | 330 } |
331 | 331 |
332 #if 0 | 332 #if 0 |
333 printf("## vars= %d, regs= %d/%d, args= %d, extra= %d\n", | 333 printf("## vars= %d, regs= %d/%d, args= %d, extra= %d\n", |
334 round16(-disp), | 334 round16(-disp), |
335 max_reg_var+2, | 335 max_reg_var+2, |
336 max_reg_var, | 336 max_reg_var, |
337 round16(max_func_args*SIZE_OF_INT), | 337 round16(max_func_args*SIZE_OF_INT), |
338 0 | 338 0 |
339 ); | 339 ); |
340 printf("## callee arg top=\t%d\n",CALLEE_ARG(0)); | 340 printf("## callee arg top=\t%d\n",CALLEE_ARG(0)); |
341 printf("## reg_save_top=\t\t%d\n",r1_offsetv); | 341 printf("## reg_save_top=\t\t%d\n",r1_offsetv); |
342 printf("## reg_save_end=\t\t%d\n", | 342 printf("## reg_save_end=\t\t%d\n", |
343 -max_reg_var*SIZE_OF_INT-max_reg_var*SIZE_OF_FLOAT-2*SIZE_OF_INT+ | 343 -max_reg_var*SIZE_OF_INT-max_reg_var*SIZE_OF_FLOAT-2*SIZE_OF_INT+ |
344 r1_offsetv); | 344 r1_offsetv); |
345 printf("## lvar_offset=\t\t%d %d\n",lvar_offsetv,lvar_offsetv%16); | 345 printf("## lvar_offset=\t\t%d %d\n",lvar_offsetv,lvar_offsetv%16); |
346 printf("## min local var=\t%d\n",FUNC_LVAR(0)+lvar_offsetv); | 346 printf("## min local var=\t%d\n",FUNC_LVAR(0)+lvar_offsetv); |
347 printf("## max local var=\t%d\n",FUNC_LVAR(disp)+lvar_offsetv); | 347 printf("## max local var=\t%d\n",FUNC_LVAR(disp)+lvar_offsetv); |
348 printf("## min caller arg var=\t%d\n", | 348 printf("## min caller arg var=\t%d\n", |
349 CALLER_ARG(round16(max_func_args*SIZE_OF_INT))); | 349 CALLER_ARG(round16(max_func_args*SIZE_OF_INT))); |
350 printf("## max caller arg var=\t%d\n",CALLER_ARG(0)); | 350 printf("## max caller arg var=\t%d\n",CALLER_ARG(0)); |
351 printf("##\n"); | 351 printf("##\n"); |
352 #endif | 352 #endif |
353 | 353 |
354 return 0; | 354 return 0; |
363 lvar_intro(int l) | 363 lvar_intro(int l) |
364 { | 364 { |
365 int large; | 365 int large; |
366 if (is_code(fnptr)) { | 366 if (is_code(fnptr)) { |
367 if (l>=ARG_LVAR_OFFSET) { | 367 if (l>=ARG_LVAR_OFFSET) { |
368 large = LARGE_OFFSET(CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); | 368 large = LARGE_OFFSET(CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); |
369 } else | 369 } else |
370 large = LARGE_OFFSET(CODE_LVAR(l)); | 370 large = LARGE_OFFSET(CODE_LVAR(l)); |
371 } else if (l<0) { /* local variable */ | 371 } else if (l<0) { /* local variable */ |
372 large = LARGE_OFFSET(FUNC_LVAR(l)); | 372 large = LARGE_OFFSET(FUNC_LVAR(l)); |
373 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 373 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
374 large = LARGE_OFFSET(CALLER_ARG(l-ARG_LVAR_OFFSET)); | 374 large = LARGE_OFFSET(CALLER_ARG(l-ARG_LVAR_OFFSET)); |
375 } else { /* callee's arguments */ | 375 } else { /* callee's arguments */ |
376 large = LARGE_OFFSET(CALLEE_ARG(l)); | 376 large = LARGE_OFFSET(CALLEE_ARG(l)); |
377 } | 377 } |
378 if (large) { | 378 if (large) { |
379 large_lvar = get_register(); | 379 large_lvar = get_register(); |
380 lvar_address(l,large_lvar); | 380 lvar_address(l,large_lvar); |
381 } else { | 381 } else { |
382 large_lvar = 0; | 382 large_lvar = 0; |
383 } | 383 } |
384 } | 384 } |
385 | 385 |
386 static void | 386 static void |
387 lvar(int l,char *cext) | 387 lvar(int l,char *cext) |
388 { | 388 { |
389 if (large_lvar) { | 389 if (large_lvar) { |
390 printf("0(%s)\n",register_name(large_lvar)); | 390 printf("0(%s)\n",register_name(large_lvar)); |
391 free_register(large_lvar); | 391 free_register(large_lvar); |
392 return; | 392 return; |
393 } | 393 } |
394 if (is_code(fnptr)) { | 394 if (is_code(fnptr)) { |
395 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 395 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
396 printf("%d($sp)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); | 396 printf("%d($sp)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); |
397 } else { | 397 } else { |
398 printf("%d($sp)\n",CODE_LVAR(l)); | 398 printf("%d($sp)\n",CODE_LVAR(l)); |
399 } | 399 } |
400 } else if (l<0) { /* local variable */ | 400 } else if (l<0) { /* local variable */ |
401 printf(".LC%d+%d($sp)\n",lvar_offset_label,FUNC_LVAR(l)); | 401 printf(".LC%d+%d($sp)\n",lvar_offset_label,FUNC_LVAR(l)); |
402 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 402 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
403 printf("%d($sp)%s\n",CALLER_ARG(l-ARG_LVAR_OFFSET),cext); | 403 printf("%d($sp)%s\n",CALLER_ARG(l-ARG_LVAR_OFFSET),cext); |
404 } else { /* callee's arguments */ | 404 } else { /* callee's arguments */ |
413 | 413 |
414 int tmp = -1; | 414 int tmp = -1; |
415 char *trn; | 415 char *trn; |
416 if (is_code(fnptr)) { | 416 if (is_code(fnptr)) { |
417 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 417 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
418 code_add(creg,CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),REG_sp); | 418 code_add(creg,CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),REG_sp); |
419 } else | 419 } else |
420 code_add(creg,CODE_LVAR(l),REG_fp); | 420 code_add(creg,CODE_LVAR(l),REG_fp); |
421 } else if (l<0) { /* local variable */ | 421 } else if (l<0) { /* local variable */ |
422 trn = register_name(tmp = get_register()); | 422 trn = register_name(tmp = get_register()); |
423 printf("\tlqd\t%s, 64($sp)\n",trn); | 423 printf("\tlqd\t%s, 64($sp)\n",trn); |
424 printf("\ta\t%s, $sp, %s\n",register_name(creg),trn); | 424 printf("\ta\t%s, $sp, %s\n",register_name(creg),trn); |
425 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 425 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
426 code_add(creg,CALLER_ARG(l-ARG_LVAR_OFFSET),REG_sp); | 426 code_add(creg,CALLER_ARG(l-ARG_LVAR_OFFSET),REG_sp); |
427 } else { /* callee's arguments */ | 427 } else { /* callee's arguments */ |
428 code_add(creg,CALLEE_ARG(l),REG_fp); | 428 code_add(creg,CALLEE_ARG(l),REG_fp); |
429 } | 429 } |
430 if (tmp!=-1) free_register(tmp); | 430 if (tmp!=-1) free_register(tmp); |
431 } | 431 } |
432 | 432 |
433 | 433 |
504 regs[n->dsp]= INPUT_REG; | 504 regs[n->dsp]= INPUT_REG; |
505 reg_var++; | 505 reg_var++; |
506 caddr(args)=SIZE_OF_INT; | 506 caddr(args)=SIZE_OF_INT; |
507 } | 507 } |
508 } else if (type==FLOAT) { | 508 } else if (type==FLOAT) { |
509 if (is_function(fnptr)) { | 509 if (is_function(fnptr)) { |
510 if ((reg = get_input_dregister_var(reg_var,n,is_code0,0))) { | 510 if ((reg = get_input_dregister_var(reg_var,n,is_code0,0))) { |
511 n->sc = REGISTER; | 511 n->sc = REGISTER; |
512 n->dsp = cadr(reg); | 512 n->dsp = cadr(reg); |
513 regs[n->dsp]= INPUT_REG; | 513 regs[n->dsp]= INPUT_REG; |
514 reg_var++; | 514 reg_var++; |
515 caddr(args)=size(type); | 515 caddr(args)=size(type); |
516 } | 516 } |
517 } else { | 517 } else { |
518 if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { | 518 if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { |
519 n->sc = FREGISTER; | 519 n->sc = FREGISTER; |
520 n->dsp = cadr(reg); | 520 n->dsp = cadr(reg); |
521 regs[n->dsp]= INPUT_REG; | 521 regs[n->dsp]= INPUT_REG; |
522 freg_var++; | 522 freg_var++; |
523 caddr(args)=size(type); | 523 caddr(args)=size(type); |
524 } | 524 } |
525 } | 525 } |
526 } else if (type==DOUBLE) { | 526 } else if (type==DOUBLE) { |
527 if ((reg = get_input_dregister_var(reg_var,n,is_code0,1))) { | 527 if ((reg = get_input_dregister_var(reg_var,n,is_code0,1))) { |
528 n->sc = LREGISTER; | 528 n->sc = LREGISTER; |
529 n->dsp = cadr(reg); | 529 n->dsp = cadr(reg); |
530 regs[i=n->dsp]= INPUT_DREG; | 530 regs[i=n->dsp]= INPUT_DREG; |
545 } | 545 } |
546 } | 546 } |
547 args = cadr(args); | 547 args = cadr(args); |
548 } | 548 } |
549 if (is_function(fnptr)) | 549 if (is_function(fnptr)) |
550 code_save_input_registers(dots); | 550 code_save_input_registers(dots); |
551 } | 551 } |
552 | 552 |
553 | 553 |
554 int | 554 int |
555 get_register(void) | 555 get_register(void) |
556 { /* 使われていないレジスタを調べる */ | 556 { /* 使われていないレジスタを調べる */ |
557 int i,j,reg; | 557 int i,j,reg; |
558 for(i=MAX_TMP_REG;i>=MIN_TMP_REG;i--) { | 558 for(i=MAX_TMP_REG;i>=MIN_TMP_REG;i--) { |
559 if (regs[i]) continue; /* 使われている */ | 559 if (regs[i]) continue; /* 使われている */ |
560 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | 560 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ |
561 return i; /* その場所を表す番号を返す */ | 561 return i; /* その場所を表す番号を返す */ |
562 } | 562 } |
563 for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) { | 563 for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) { |
564 reg =REG_VAR_BASE+i; | 564 reg =REG_VAR_BASE+i; |
565 if (! regs[reg]) { /* 使われていないなら */ | 565 if (! regs[reg]) { /* 使われていないなら */ |
566 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ | 566 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ |
567 if (i+1>max_reg_var) max_reg_var=i+1; | 567 if (i+1>max_reg_var) max_reg_var=i+1; |
568 return reg; /* その場所を表す番号を返す */ | 568 return reg; /* その場所を表す番号を返す */ |
569 } | 569 } |
570 } | 570 } |
571 /* search register stack */ | 571 /* search register stack */ |
572 for(i=0;i<reg_sp;i++) { | 572 for(i=0;i<reg_sp;i++) { |
573 if ((reg=reg_stack[i])>0) { | 573 if ((reg=reg_stack[i])>0) { |
574 code_assign_lvar( | 574 code_assign_lvar( |
575 (j=new_lvar(SIZE_OF_INT)*4),reg,0); | 575 (j=new_lvar(SIZE_OF_INT)*4),reg,0); |
576 reg_stack[i]= j-REG_LVAR_OFFSET; | 576 reg_stack[i]= j-REG_LVAR_OFFSET; |
577 return reg; | 577 return reg; |
578 } | 578 } |
579 } | 579 } |
580 for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) { | 580 for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) { |
581 reg =REG_VAR_BASE+i; | 581 reg =REG_VAR_BASE+i; |
582 } | 582 } |
583 /* あいている場所がないなら、エラー(いったい誰が使ってるの?) */ | 583 /* あいている場所がないなら、エラー(いったい誰が使ってるの?) */ |
585 } | 585 } |
586 | 586 |
587 int | 587 int |
588 pop_register(void) | 588 pop_register(void) |
589 { /* レジスタから値を取り出す */ | 589 { /* レジスタから値を取り出す */ |
590 return reg_stack[--reg_sp]; | 590 return reg_stack[--reg_sp]; |
591 } | 591 } |
592 | 592 |
593 #if FLOAT_CODE | 593 #if FLOAT_CODE |
594 int | 594 int |
595 get_dregister(int d) | 595 get_dregister(int d) |
599 | 599 |
600 | 600 |
601 int | 601 int |
602 pop_fregister(void) | 602 pop_fregister(void) |
603 { /* レジスタから値を取り出す */ | 603 { /* レジスタから値を取り出す */ |
604 return reg_stack[--reg_sp]; | 604 return reg_stack[--reg_sp]; |
605 } | 605 } |
606 #endif | 606 #endif |
607 | 607 |
608 // static int lreg_count; | 608 // static int lreg_count; |
609 int | 609 int |
610 get_lregister0() | 610 get_lregister0() |
611 { | 611 { |
612 return get_register(); | 612 return get_register(); |
613 } | 613 } |
614 | 614 |
615 int | 615 int |
616 get_lregister() | 616 get_lregister() |
617 { | 617 { |
618 return get_register(); | 618 return get_register(); |
619 } | 619 } |
620 | 620 |
621 int | 621 int |
622 get_lregister_var(NMTBL *n) | 622 get_lregister_var(NMTBL *n) |
623 { | 623 { |
624 return get_register_var(n); | 624 return get_register_var(n); |
625 } | 625 } |
626 | 626 |
627 void | 627 void |
628 emit_pop_free(int xreg) | 628 emit_pop_free(int xreg) |
629 { | 629 { |
630 if (xreg>=0 && xreg!=creg) | 630 if (xreg>=0 && xreg!=creg) |
631 free_register(xreg); | 631 free_register(xreg); |
632 } | 632 } |
633 | 633 |
634 void | 634 void |
635 | 635 |
636 free_register(int i) { /* いらなくなったレジスタを解放 */ | 636 free_register(int i) { /* いらなくなったレジスタを解放 */ |
646 int | 646 int |
647 get_input_dregister_var(int i,NMTBL *n,int is_code,int d) | 647 get_input_dregister_var(int i,NMTBL *n,int is_code,int d) |
648 { | 648 { |
649 int j; | 649 int j; |
650 if (is_code) { | 650 if (is_code) { |
651 if(i>MAX_CODE_INPUT_DREGISTER_VAR) return 0; | 651 if(i>MAX_CODE_INPUT_DREGISTER_VAR) return 0; |
652 i = FREG_VAR_BASE+i+FREG_OFFSET; | 652 i = FREG_VAR_BASE+i+FREG_OFFSET; |
653 use_input_reg(i,1); | 653 use_input_reg(i,1); |
654 return list3n(FREGISTER,i,n); | 654 return list3n(FREGISTER,i,n); |
655 } | 655 } |
656 if (d) { | 656 if (d) { |
657 j = get_input_lregister_var(i,n,is_code); | 657 j = get_input_lregister_var(i,n,is_code); |
658 return j; | 658 return j; |
659 } else { | 659 } else { |
660 if (i==0) return list3n(REGISTER,1,n); | 660 if (i==0) return list3n(REGISTER,1,n); |
661 else if (i==1) return list3n(REGISTER,2,n); | 661 else if (i==1) return list3n(REGISTER,2,n); |
662 else if (i==2) return list3n(REGISTER,3,n); | 662 else if (i==2) return list3n(REGISTER,3,n); |
663 else if (i==3) return list3n(REGISTER,4,n); | 663 else if (i==3) return list3n(REGISTER,4,n); |
664 else return 0; | 664 else return 0; |
665 } | 665 } |
666 } | 666 } |
667 | 667 |
668 int | 668 int |
669 get_input_lregister_var(int i,NMTBL *n,int is_code) | 669 get_input_lregister_var(int i,NMTBL *n,int is_code) |
670 { | 670 { |
671 return get_input_register_var(i,n,is_code); | 671 return get_input_register_var(i,n,is_code); |
672 } | 672 } |
673 | 673 |
674 int | 674 int |
675 get_input_register_var(int i,NMTBL *n,int is_code) | 675 get_input_register_var(int i,NMTBL *n,int is_code) |
676 { | 676 { |
677 if (is_code) { | 677 if (is_code) { |
678 if(!(i<REG_VAR_MAX-REG_VAR_MIN)) return 0; | 678 if(!(i<REG_VAR_MAX-REG_VAR_MIN)) return 0; |
679 i = REG_VAR_BASE+i; | 679 i = REG_VAR_BASE+i; |
680 use_input_reg(i,1); | 680 use_input_reg(i,1); |
681 } else { | 681 } else { |
682 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; | 682 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; |
683 i = i+MIN_TMP_REG; | 683 i = i+MIN_TMP_REG; |
684 } | 684 } |
685 return list3n(REGISTER,i,n); | 685 return list3n(REGISTER,i,n); |
686 } | 686 } |
687 | 687 |
688 | 688 |
716 extern int | 716 extern int |
717 code_register_overlap(int s,int t) | 717 code_register_overlap(int s,int t) |
718 { | 718 { |
719 switch(car(s)) { | 719 switch(car(s)) { |
720 case REGISTER: case FREGISTER: case DREGISTER: case LREGISTER: | 720 case REGISTER: case FREGISTER: case DREGISTER: case LREGISTER: |
721 switch(car(t)) { | 721 switch(car(t)) { |
722 case REGISTER: case FREGISTER: case DREGISTER: case LREGISTER: | 722 case REGISTER: case FREGISTER: case DREGISTER: case LREGISTER: |
723 return cadr(s)==cadr(t); | 723 return cadr(s)==cadr(t); |
724 } | 724 } |
725 } | 725 } |
726 return 0; | 726 return 0; |
727 } | 727 } |
728 | 728 |
729 void | 729 void |
736 if (!lsrc) return; | 736 if (!lsrc) return; |
737 printf("## %d: %s:",lineno,s); | 737 printf("## %d: %s:",lineno,s); |
738 #if 1 | 738 #if 1 |
739 for(j=0,i=1;i<MAX_REGISTER;i++) if (regs[i]) j++; | 739 for(j=0,i=1;i<MAX_REGISTER;i++) if (regs[i]) j++; |
740 if (j>USAGE_MAX) { | 740 if (j>USAGE_MAX) { |
741 // printf("\n# regs:01234567890123456789012"); | 741 // printf("\n# regs:01234567890123456789012"); |
742 printf("\n# regs:"); | 742 printf("\n# regs:"); |
743 for(i=1;i<MAX_REGISTER;i++) { printf("%d",regs[i]); } | 743 for(i=1;i<MAX_REGISTER;i++) { printf("%d",regs[i]); } |
744 } | 744 } |
745 if (reg_sp>0) { | 745 if (reg_sp>0) { |
746 printf(" stack "); | 746 printf(" stack "); |
747 for(i=reg_sp;i>0;i--) { | 747 for(i=reg_sp;i>0;i--) { |
748 if(reg_stack[i-1]>=0) { | 748 if(reg_stack[i-1]>=0) { |
749 printf(" %s",register_name(reg_stack[i-1])); | 749 printf(" %s",register_name(reg_stack[i-1])); |
750 } else | 750 } else |
751 printf(",%d",reg_stack[i-1]); | 751 printf(",%d",reg_stack[i-1]); |
752 } | 752 } |
753 } | 753 } |
754 #endif | 754 #endif |
755 printf("\n"); | 755 printf("\n"); |
756 } | 756 } |
757 | 757 |
784 get_register_var(NMTBL *n) | 784 get_register_var(NMTBL *n) |
785 { | 785 { |
786 int i,j; | 786 int i,j; |
787 int max = n?REG_VAR_USER_MAX-REG_VAR_BASE:REG_VAR_MAX-REG_VAR_BASE; | 787 int max = n?REG_VAR_USER_MAX-REG_VAR_BASE:REG_VAR_MAX-REG_VAR_BASE; |
788 for(i=0;i<max;i++) { | 788 for(i=0;i<max;i++) { |
789 j = reg_var_num(i); | 789 j = reg_var_num(i); |
790 if (! regs[j]) { | 790 if (! regs[j]) { |
791 regs[j]=USING_REG; | 791 regs[j]=USING_REG; |
792 if (i+1>=max_reg_var) max_reg_var=i+1; | 792 if (i+1>=max_reg_var) max_reg_var=i+1; |
793 return list3n(REGISTER,j,n); | 793 return list3n(REGISTER,j,n); |
794 } | 794 } |
795 } | 795 } |
796 return list3n(LVAR,new_lvar(SIZE_OF_INT),n); | 796 return list3n(LVAR,new_lvar(SIZE_OF_INT),n); |
797 } | 797 } |
798 | 798 |
799 #define freg_var_num(i) (FREG_VAR_BASE+i+FREG_OFFSET) | 799 #define freg_var_num(i) (FREG_VAR_BASE+i+FREG_OFFSET) |
801 int | 801 int |
802 get_dregister_var(NMTBL *n,int d) | 802 get_dregister_var(NMTBL *n,int d) |
803 { | 803 { |
804 int i,j; | 804 int i,j; |
805 for(i=0;i<FREG_VAR_MAX-FREG_VAR_BASE;i++) { | 805 for(i=0;i<FREG_VAR_MAX-FREG_VAR_BASE;i++) { |
806 j = freg_var_num(i); | 806 j = freg_var_num(i); |
807 if (! regs[j]) { /* 使われていないなら */ | 807 if (! regs[j]) { /* 使われていないなら */ |
808 regs[j]=USING_REG; /* そのレジスタを使うことを宣言し */ | 808 regs[j]=USING_REG; /* そのレジスタを使うことを宣言し */ |
809 if (i+1>max_reg_var) max_reg_var=i+1; | 809 if (i+1>max_reg_var) max_reg_var=i+1; |
810 /* その場所を表す番号を返す */ | 810 /* その場所を表す番号を返す */ |
811 return list3n(FREGISTER,j,n); | 811 return list3n(FREGISTER,j,n); |
812 } | 812 } |
813 } | 813 } |
814 return list3n(LVAR,new_lvar(SIZE_OF_INT),n); | 814 return list3n(LVAR,new_lvar(SIZE_OF_INT),n); |
815 } | 815 } |
816 | 816 |
817 int | 817 int |
832 emit_pop(int type) | 832 emit_pop(int type) |
833 { | 833 { |
834 int xreg,reg; | 834 int xreg,reg; |
835 xreg=pop_register(); | 835 xreg=pop_register(); |
836 // REG_LVAR_OFFSET = 2 | 836 // REG_LVAR_OFFSET = 2 |
837 if (xreg<= -REG_LVAR_OFFSET) { | 837 if (xreg<= -REG_LVAR_OFFSET) { |
838 reg = get_register(); | 838 reg = get_register(); |
839 code_rlvar(REG_LVAR_OFFSET+xreg,reg); | 839 code_rlvar(REG_LVAR_OFFSET+xreg,reg); |
840 free_lvar(REG_LVAR_OFFSET+xreg); | 840 free_lvar(REG_LVAR_OFFSET+xreg); |
841 //free_lvar(-4); | 841 //free_lvar(-4); |
842 xreg = reg; | 842 xreg = reg; |
843 } | 843 } |
844 return xreg; | 844 return xreg; |
845 } | 845 } |
846 | 846 |
847 static int const_list; | 847 static int const_list; |
862 } | 862 } |
863 | 863 |
864 extern void | 864 extern void |
865 code_const(int e2,int reg) { | 865 code_const(int e2,int reg) { |
866 char *crn; | 866 char *crn; |
867 int r; | 867 int r; |
868 //code_const0(e2,reg,""); | 868 //code_const0(e2,reg,""); |
869 // printf("code_const\n"); | 869 // printf("code_const\n"); |
870 /************************************************************ | 870 /************************************************************ |
871 * ここでp1の値によって、命令が異なる...... * | 871 * ここでp1の値によって、命令が異なる...... * |
872 * il命令は-32768~32767 * | 872 * il命令は-32768~32767 * |
873 * ila命令は262143まで * | 873 * ila命令は262143まで * |
874 * それ以上はilhuとiohlを混合して使う。 * | 874 * それ以上はilhuとiohlを混合して使う。 * |
875 * example:15728639 * | 875 * example:15728639 * |
876 * 15728639/16^4 = 239 ilhu $4,239 * | 876 * 15728639/16^4 = 239 ilhu $4,239 * |
877 * 15728639%16^4 = 65535 iohl $4,65535 * | 877 * 15728639%16^4 = 65535 iohl $4,65535 * |
878 *負の場合も異なる * | 878 *負の場合も異なる * |
879 * example : -99999 fffe7961 * | 879 * example : -99999 fffe7961 * |
880 * r = ~(-99999) r = (r >> 16) & 0xffff; r += 1; r=-r;* | 880 * r = ~(-99999) r = (r >> 16) & 0xffff; r += 1; r=-r;* |
881 * ilhu $4,-2 * | 881 * ilhu $4,-2 * |
882 * -99999 & 0xfff iohl $4,31073 -> 0x7961 * | 882 * -99999 & 0xfff iohl $4,31073 -> 0x7961 * |
883 * example : -15728639 ff100001 * | 883 * example : -15728639 ff100001 * |
884 ***********************************************************/ | 884 ***********************************************************/ |
885 use_int(reg); | 885 use_int(reg); |
886 crn = register_name(reg); | 886 crn = register_name(reg); |
887 if (-32768<e2&&e2<32768) | 887 if (-32768<e2&&e2<32768) |
888 printf("\til %s,%d\n",crn,e2); | 888 printf("\til %s,%d\n",crn,e2); |
889 else if(32767<e2&&e2<262144) | 889 else if(32767<e2&&e2<262144) |
890 printf("\tila %s,%d\n",crn,e2); | 890 printf("\tila %s,%d\n",crn,e2); |
891 else if(262143<e2) { | 891 else if(262143<e2) { |
892 printf("\t ilhu\t%s,%d\n",crn,e2/65536); | 892 printf("\t ilhu\t%s,%d\n",crn,e2/65536); |
893 printf("\t iohl %s,%d\n",crn,e2%65536); | 893 printf("\t iohl %s,%d\n",crn,e2%65536); |
894 } else { | 894 } else { |
895 r = (~e2 >> 16) & 0xffff; | 895 r = (~e2 >> 16) & 0xffff; |
896 r += 1; | 896 r += 1; |
897 r = -r; | 897 r = -r; |
898 printf("\tilhu\t%s,%d\n",crn,r); | 898 printf("\tilhu\t%s,%d\n",crn,r); |
899 if((e2&0xffff) > -262143) | 899 if((e2&0xffff) > -262143) |
900 printf("\tiohl %s,%d\n",crn, (e2&0xffff)); | 900 printf("\tiohl %s,%d\n",crn, (e2&0xffff)); |
901 else | 901 else |
902 printf("\tori %s,%s,%d\n",crn,crn,(e2&0xffff)); | 902 printf("\tori %s,%s,%d\n",crn,crn,(e2&0xffff)); |
903 } | 903 } |
904 } | 904 } |
905 | 905 |
906 static void | 906 static void |
907 code_add(int reg,int offset,int r) | 907 code_add(int reg,int offset,int r) |
908 { | 908 { |
909 char *crn = register_name(reg); | 909 char *crn = register_name(reg); |
910 char *rrn = register_name(r); | 910 char *rrn = register_name(r); |
911 // char *rn2 = register_name(r+1); | 911 // char *rn2 = register_name(r+1); |
912 char *drn; | 912 char *drn; |
913 int dreg; | 913 int dreg; |
914 if (offset==0) { | 914 if (offset==0) { |
915 if(r!=reg) | 915 if(r!=reg) |
916 printf("\tori\t%s, %s, 0\n",crn,rrn); | 916 printf("\tori\t%s, %s, 0\n",crn,rrn); |
917 } else if (-32768<offset&&offset<32768) | 917 } else if (-32768<offset&&offset<32768) |
918 printf("\tai\t%s, %s, %d\n",crn,rrn,offset); | 918 printf("\tai\t%s, %s, %d\n",crn,rrn,offset); |
919 } else { | 919 } else { |
920 drn = register_name(dreg = get_register()); | 920 drn = register_name(dreg = get_register()); |
921 code_const(offset, dreg); | 921 code_const(offset, dreg); |
922 printf("\ta\t%s, %s, %s\n",crn,drn,rrn); | 922 printf("\ta\t%s, %s, %s\n",crn,drn,rrn); |
923 free_register(dreg); | 923 free_register(dreg); |
924 } | 924 } |
925 } | 925 } |
926 | 926 |
927 | 927 |
928 static void | 928 static void |
929 code_ld(char *ld,int reg,int offset,int r) | 929 code_ld(char *ld,int reg,int offset,int r) |
930 { | 930 { |
931 char *crn = register_name(reg); | 931 char *crn = register_name(reg); |
932 char *rrn = register_name(r); | 932 char *rrn = register_name(r); |
933 if (-1024<offset&&offset<1024) { | 933 if (-1024<offset&&offset<1024) { |
934 printf("\t%s\t%s, %d(%s)\n",ld,crn,offset,rrn); | 934 printf("\t%s\t%s, %d(%s)\n",ld,crn,offset,rrn); |
935 } else { | 935 } else { |
936 code_add(reg,offset,r); | 936 code_add(reg,offset,r); |
937 printf("\t%s\t%s, 0(%s)\n",ld,crn,crn); | 937 printf("\t%s\t%s, 0(%s)\n",ld,crn,crn); |
938 } | 938 } |
939 } | 939 } |
940 | 940 |
941 /* | 941 /* |
942 | 942 |
980 | 980 |
981 void | 981 void |
982 code_register(int e2,int reg) { | 982 code_register(int e2,int reg) { |
983 use_int(reg); | 983 use_int(reg); |
984 if (reg!=e2) { | 984 if (reg!=e2) { |
985 printf("\tori\t%s, %s, 0\n",register_name(reg),register_name(e2)); | 985 printf("\tori\t%s, %s, 0\n",register_name(reg),register_name(e2)); |
986 } | 986 } |
987 } | 987 } |
988 | 988 |
989 | 989 |
990 void | 990 void |
1013 } | 1013 } |
1014 | 1014 |
1015 extern void | 1015 extern void |
1016 code_u2us(int reg) | 1016 code_u2us(int reg) |
1017 { | 1017 { |
1018 // &! ということらしい、だけど16711680とかは使えない。よってilhuとかで16711680をレジスタに格納して | 1018 // &! ということらしい、だけど16711680とかは使えない。よってilhuとかで16711680をレジスタに格納して |
1019 // and rt,rs,ra でandを行えば良いが、!はどうすんだ? | 1019 // and rt,rs,ra でandを行えば良いが、!はどうすんだ? |
1020 use_int(reg); | 1020 use_int(reg); |
1021 //printf("bic\t%s, %s, #16711680\n",register_name(reg),register_name(reg)); | 1021 //printf("bic\t%s, %s, #16711680\n",register_name(reg),register_name(reg)); |
1022 printf("\tilhu\t%s,255\n", register_name(reg+1)); | 1022 printf("\tilhu\t%s,255\n", register_name(reg+1)); |
1023 printf("\tand\t%s,%s,%s\n",register_name(reg),register_name(reg),register_name(reg+1)); | 1023 printf("\tand\t%s,%s,%s\n",register_name(reg),register_name(reg),register_name(reg+1)); |
1024 //printf("bic\t%s, %s, #-16777216\n",register_name(reg),register_name(reg)); | 1024 //printf("bic\t%s, %s, #-16777216\n",register_name(reg),register_name(reg)); |
1025 printf("\tilhu\t%s,-256\n", register_name(reg+1)); | 1025 printf("\tilhu\t%s,-256\n", register_name(reg+1)); |
1026 printf("\tand\t%s,%s,%s\n",register_name(reg),register_name(reg),register_name(reg+1)); | 1026 printf("\tand\t%s,%s,%s\n",register_name(reg),register_name(reg),register_name(reg+1)); |
1027 } | 1027 } |
1028 | 1028 |
1029 static void | 1029 static void |
1030 cext(int sz, int sign, int from, int to) | 1030 cext(int sz, int sign, int from, int to) |
1031 { | 1031 { |
1032 if (sz==1 && !sign) { | 1032 if (sz==1 && !sign) { |
1033 // unsigned char | 1033 // unsigned char |
1034 printf(" rotqbyi %s,%s,13\n",fn,fn); | 1034 printf(" rotqbyi %s,%s,13\n",fn,fn); |
1035 printf(" andi %s,%s,0x00ff\n",tn,fn); | 1035 printf(" andi %s,%s,0x00ff\n",tn,fn); |
1036 } else if (sz==1 && sign) { | 1036 } else if (sz==1 && sign) { |
1037 // signed char | 1037 // signed char |
1038 printf(" rotqbyi %s,%s,13\n",fn,fn); | 1038 printf(" rotqbyi %s,%s,13\n",fn,fn); |
1039 printf(" xsbh %s,%s\n",fn,fn); | 1039 printf(" xsbh %s,%s\n",fn,fn); |
1040 printf(" xshw %s,%s\n",tn,fn); | 1040 printf(" xshw %s,%s\n",tn,fn); |
1041 } else if (sz==2 && !sign) { | 1041 } else if (sz==2 && !sign) { |
1042 // unsigned short | 1042 // unsigned short |
1043 int t = get_register(); | 1043 int t = get_register(); |
1044 char *tmp = register_name(t); | 1044 char *tmp = register_name(t); |
1045 printf(" rotqbyi %s,%s,14\n",fn,fn); | 1045 printf(" rotqbyi %s,%s,14\n",fn,fn); |
1046 printf(" ori %s,%s,0\n",tmp,fn); | 1046 printf(" ori %s,%s,0\n",tmp,fn); |
1047 printf(" ila %s,65535\n",fn,fn); | 1047 printf(" ila %s,65535\n",fn,fn); |
1048 printf(" and %s,%s,%s\n",tn,tmp,fn); | 1048 printf(" and %s,%s,%s\n",tn,tmp,fn); |
1049 free_register(t); | 1049 free_register(t); |
1050 } else if (sz==2 && !sign) { | 1050 } else if (sz==2 && !sign) { |
1051 // singed short | 1051 // singed short |
1052 printf(" rotqbyi %s,%s,14\n",fn,fn); | 1052 printf(" rotqbyi %s,%s,14\n",fn,fn); |
1053 printf(" xshw %s,%s\n",tn,fn); | 1053 printf(" xshw %s,%s\n",tn,fn); |
1054 } | 1054 } |
1055 } | 1055 } |
1056 | 1056 |
1057 static void | 1057 static void |
1058 shuffle_offset(int sz, int offset, int base, int to) | 1058 shuffle_offset(int sz, int offset, int base, int to) |
1060 int tmp = get_register(); | 1060 int tmp = get_register(); |
1061 char *bn = register_name(base); | 1061 char *bn = register_name(base); |
1062 char *tn = register_name(tmp); | 1062 char *tn = register_name(tmp); |
1063 | 1063 |
1064 if (sz==1) { | 1064 if (sz==1) { |
1065 printf(" cbd %s %d(%s)\n",tn,offset, bn); | 1065 printf(" cbd %s %d(%s)\n",tn,offset, bn); |
1066 printf(" shufb %s,%s,%s,%s\n",tn,fn,tn); | 1066 printf(" shufb %s,%s,%s,%s\n",tn,fn,tn); |
1067 } else if (sz==1 && sign) { | 1067 } else if (sz==1 && sign) { |
1068 // signed char | 1068 // signed char |
1069 printf(" rotqbyi %s,%s,13\n",fn,fn); | 1069 printf(" rotqbyi %s,%s,13\n",fn,fn); |
1070 printf(" xsbh %s,%s\n",fn,fn); | 1070 printf(" xsbh %s,%s\n",fn,fn); |
1071 printf(" xshw %s,%s\n",tn,fn); | 1071 printf(" xshw %s,%s\n",tn,fn); |
1072 } else if (sz==2 && !sign) { | 1072 } else if (sz==2 && !sign) { |
1073 // unsigned short | 1073 // unsigned short |
1074 int t = get_register(); | 1074 int t = get_register(); |
1075 char *tmp = register_name(t); | 1075 char *tmp = register_name(t); |
1076 printf(" rotqbyi %s,%s,14\n",fn,fn); | 1076 printf(" rotqbyi %s,%s,14\n",fn,fn); |
1077 printf(" ori %s,%s,0\n",tmp,fn); | 1077 printf(" ori %s,%s,0\n",tmp,fn); |
1078 printf(" ila %s,65535\n",fn,fn); | 1078 printf(" ila %s,65535\n",fn,fn); |
1079 printf(" and %s,%s,%s\n",tn,tmp,fn); | 1079 printf(" and %s,%s,%s\n",tn,tmp,fn); |
1080 free_register(t); | 1080 free_register(t); |
1081 } else if (sz==2 && !sign) { | 1081 } else if (sz==2 && !sign) { |
1082 // singed short | 1082 // singed short |
1083 printf(" rotqbyi %s,%s,14\n",fn,fn); | 1083 printf(" rotqbyi %s,%s,14\n",fn,fn); |
1084 printf(" xshw %s,%s\n",tn,fn); | 1084 printf(" xshw %s,%s\n",tn,fn); |
1085 } | 1085 } |
1086 free_register(tmp); | 1086 free_register(tmp); |
1087 } | 1087 } |
1088 | 1088 |
1089 | 1089 |
1123 | 1123 |
1124 void | 1124 void |
1125 code_not(int creg) { | 1125 code_not(int creg) { |
1126 use_int(creg); | 1126 use_int(creg); |
1127 printf("\tnor\t%s, %s, %s\n", | 1127 printf("\tnor\t%s, %s, %s\n", |
1128 register_name(creg), register_name(creg), register_name(creg)); | 1128 register_name(creg), register_name(creg), register_name(creg)); |
1129 } | 1129 } |
1130 | 1130 |
1131 | 1131 |
1132 void | 1132 void |
1133 code_lnot(int creg) { | 1133 code_lnot(int creg) { |
1139 void | 1139 void |
1140 code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) { | 1140 code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) { |
1141 char *xrn,*drn; | 1141 char *xrn,*drn; |
1142 int xreg; | 1142 int xreg; |
1143 if (car(e2)==REGISTER) { | 1143 if (car(e2)==REGISTER) { |
1144 use_int(reg); | 1144 use_int(reg); |
1145 code_add(cadr(e2),dir,cadr(e2)); | 1145 code_add(cadr(e2),dir,cadr(e2)); |
1146 if (reg!=cadr(e2)) | 1146 if (reg!=cadr(e2)) |
1147 code_register(cadr(e2),reg); | 1147 code_register(cadr(e2),reg); |
1148 return; | 1148 return; |
1149 } | 1149 } |
1150 g_expr(e2); | 1150 g_expr(e2); |
1151 if (!is_int_reg(creg)) error(-1); | 1151 if (!is_int_reg(creg)) error(-1); |
1152 xrn = register_name(xreg = creg); | 1152 xrn = register_name(xreg = creg); |
1153 if (reg==USE_CREG) { | 1153 if (reg==USE_CREG) { |
1154 reg=get_register(); if (!reg) error(-1); | 1154 reg=get_register(); if (!reg) error(-1); |
1155 drn = register_name(reg); | 1155 drn = register_name(reg); |
1156 set_ireg(reg,0); | 1156 set_ireg(reg,0); |
1157 } else { | 1157 } else { |
1158 drn = register_name(reg); | 1158 drn = register_name(reg); |
1159 } | 1159 } |
1160 code_ld(cload(sz,sign),reg,0,xreg); | 1160 code_ld(cload(sz,sign),reg,0,xreg); |
1161 code_add(reg,dir,reg); | 1161 code_add(reg,dir,reg); |
1162 code_ld(cstore(sz),drn,0,xreg); | 1162 code_ld(cstore(sz),drn,0,xreg); |
1163 } | 1163 } |
1166 void | 1166 void |
1167 code_postinc(int e1,int e2,int dir,int sign,int sz,int reg) { | 1167 code_postinc(int e1,int e2,int dir,int sign,int sz,int reg) { |
1168 char *xrn,*crn,*nrn; | 1168 char *xrn,*crn,*nrn; |
1169 int nreg,xreg; | 1169 int nreg,xreg; |
1170 if (car(e2)==REGISTER) { | 1170 if (car(e2)==REGISTER) { |
1171 use_int(reg); | 1171 use_int(reg); |
1172 code_register(cadr(e2),reg); | 1172 code_register(cadr(e2),reg); |
1173 code_add(cadr(e2),dir,cadr(e2)); | 1173 code_add(cadr(e2),dir,cadr(e2)); |
1174 return; | 1174 return; |
1175 } | 1175 } |
1176 g_expr(e2); | 1176 g_expr(e2); |
1177 if (!is_int_reg(creg)) error(-1); | 1177 if (!is_int_reg(creg)) error(-1); |
1178 crn = register_name(xreg=creg); | 1178 crn = register_name(xreg=creg); |
1179 nreg=get_register(); if (!nreg) error(-1); | 1179 nreg=get_register(); if (!nreg) error(-1); |
1180 nrn = register_name(nreg); | 1180 nrn = register_name(nreg); |
1181 if (reg==USE_CREG) { | 1181 if (reg==USE_CREG) { |
1182 reg=get_register(); if (!reg) error(-1); | 1182 reg=get_register(); if (!reg) error(-1); |
1183 xrn = register_name(reg); | 1183 xrn = register_name(reg); |
1184 set_ireg(reg,0); | 1184 set_ireg(reg,0); |
1185 } else { | 1185 } else { |
1186 xrn = register_name(reg); | 1186 xrn = register_name(reg); |
1187 } | 1187 } |
1188 code_ld(cload(sz,sign),reg,0,xreg); | 1188 code_ld(cload(sz,sign),reg,0,xreg); |
1189 code_add(nreg,dir,reg); | 1189 code_add(nreg,dir,reg); |
1190 code_ldf(cstore(sz),nrn,0,xreg); | 1190 code_ldf(cstore(sz),nrn,0,xreg); |
1191 | 1191 |
1203 | 1203 |
1204 void | 1204 void |
1205 code_environment(int creg) { | 1205 code_environment(int creg) { |
1206 /* save frame pointer */ | 1206 /* save frame pointer */ |
1207 if (is_code(fnptr)) { | 1207 if (is_code(fnptr)) { |
1208 use_int(creg); | 1208 use_int(creg); |
1209 printf("\tori\t%s, $sp, 0\n",register_name(creg),trn); | 1209 printf("\tori\t%s, $sp, 0\n",register_name(creg),trn); |
1210 } else { | 1210 } else { |
1211 //int disp,label; | 1211 //int disp,label; |
1212 use_int(creg); | 1212 use_int(creg); |
1213 printf("\tori\t%s, $sp, 0\n",register_name(creg),trn); | 1213 printf("\tori\t%s, $sp, 0\n",register_name(creg),trn); |
1214 } | 1214 } |
1215 } | 1215 } |
1216 | 1216 |
1217 static int rexpr_bool(int e1, int reg); | 1217 static int rexpr_bool(int e1, int reg); |
1218 | 1218 |
1288 char *s,*crn; | 1288 char *s,*crn; |
1289 //int lb,label; | 1289 //int lb,label; |
1290 int lb; | 1290 int lb; |
1291 NMTBL *n = ncaddr(e1); | 1291 NMTBL *n = ncaddr(e1); |
1292 if ((lb=attr_value(n,LABEL))) { | 1292 if ((lb=attr_value(n,LABEL))) { |
1293 // already defined | 1293 // already defined |
1294 return code_label_value(lb,creg) ; | 1294 return code_label_value(lb,creg) ; |
1295 //return code_label_value(lb,35) ; | 1295 //return code_label_value(lb,35) ; |
1296 } | 1296 } |
1297 | 1297 |
1298 use_int(creg); | 1298 use_int(creg); |
1299 crn = register_name(creg); | 1299 crn = register_name(creg); |
1300 | 1300 |
1340 char *trn; | 1340 char *trn; |
1341 char *drn; | 1341 char *drn; |
1342 char *memmove = "memmove"; | 1342 char *memmove = "memmove"; |
1343 int dreg = REG_ip; | 1343 int dreg = REG_ip; |
1344 | 1344 |
1345 drn = register_name(dreg); | 1345 drn = register_name(dreg); |
1346 use_int(from); | 1346 use_int(from); |
1347 use_int(to); | 1347 use_int(to); |
1348 frn = register_name(from); | 1348 frn = register_name(from); |
1349 trn = register_name(to); | 1349 trn = register_name(to); |
1350 | 1350 |
1351 /* length <0 means upward direction copy */ | 1351 /* length <0 means upward direction copy */ |
1352 switch (length) { | 1352 switch (length) { |
1353 case 0: break; | 1353 case 0: break; |
1354 case 1: case -1: | 1354 case 1: case -1: |
1355 printf("\tlqd\t%s, %d(%s)\n",drn,(offset*4),trn); | 1355 printf("\tlqd\t%s, %d(%s)\n",drn,(offset*4),trn); |
1356 printf("\tstqd\t%s,%d(%s)\n",drn,(offset*4),trn); | 1356 printf("\tstqd\t%s,%d(%s)\n",drn,(offset*4),trn); |
1357 break; | 1357 break; |
1358 case 2: case -2: | 1358 case 2: case -2: |
1359 printf("\tlqd\t%s, %d(%s)\n",drn,(offset*4),trn); | 1359 printf("\tlqd\t%s, %d(%s)\n",drn,(offset*4),trn); |
1360 printf("\tstqd\t%s,%d(%s)\n",drn,(offset*4),trn); | 1360 printf("\tstqd\t%s,%d(%s)\n",drn,(offset*4),trn); |
1361 break; | 1361 break; |
1362 case 4: case -4: | 1362 case 4: case -4: |
1363 printf("\tlqd\t%s, %d(%s)\n",drn,(offset*4),trn); | 1363 printf("\tlqd\t%s, %d(%s)\n",drn,(offset*4),trn); |
1364 printf("\tstqd\t%s,%d(%s)\n",drn,(offset*4),trn); | 1364 printf("\tstqd\t%s,%d(%s)\n",drn,(offset*4),trn); |
1365 break; | 1365 break; |
1366 default: | 1366 default: |
1367 if (length <0) { | 1367 if (length <0) { |
1368 if (length > -MAX_COPY_LEN) { | 1368 if (length > -MAX_COPY_LEN) { |
1369 for(;length<=-4;length+=4,offset-=4) | 1369 for(;length<=-4;length+=4,offset-=4) |
1370 emit_copy(from,to,-4,offset-4,0,det); | 1370 emit_copy(from,to,-4,offset-4,0,det); |
1372 emit_copy(from,to,-2,offset-2,0,det); | 1372 emit_copy(from,to,-2,offset-2,0,det); |
1373 if(length<0) | 1373 if(length<0) |
1374 emit_copy(from,to,length,offset-1,0,det); | 1374 emit_copy(from,to,length,offset-1,0,det); |
1375 break; | 1375 break; |
1376 } | 1376 } |
1377 } else if (length <=MAX_COPY_LEN) { | 1377 } else if (length <=MAX_COPY_LEN) { |
1378 for(;length>=4;length-=4,offset+=4) | 1378 for(;length>=4;length-=4,offset+=4) |
1379 emit_copy(from,to,4,offset,0,det); | 1379 emit_copy(from,to,4,offset,0,det); |
1380 for(;length>=2;length-=2,offset+=2) | 1380 for(;length>=2;length-=2,offset+=2) |
1381 emit_copy(from,to,2,offset,0,det); | 1381 emit_copy(from,to,2,offset,0,det); |
1382 if(length>0) | 1382 if(length>0) |
1383 emit_copy(from,to,length,offset,0,det); | 1383 emit_copy(from,to,length,offset,0,det); |
1384 break; | 1384 break; |
1385 } | 1385 } |
1386 clear_ptr_cache(); | 1386 clear_ptr_cache(); |
1387 code_save_stacks(); | 1387 code_save_stacks(); |
1388 parallel_rassign(list3(1,list3(2,0,from),to)); | 1388 parallel_rassign(list3(1,list3(2,0,from),to)); |
1389 code_const(length>0?length:-length,3); | 1389 code_const(length>0?length:-length,3); |
1390 /* overlap must be allowed */ | 1390 /* overlap must be allowed */ |
1391 // offset have to be ignored */ | 1391 // offset have to be ignored */ |
1392 //printf("\thbra\t%s\n",memmove); | 1392 //printf("\thbra\t%s\n",memmove); |
1393 extern_define(memmove,0,FUNCTION,1); | 1393 extern_define(memmove,0,FUNCTION,1); |
1394 set_ireg(RET_REGISTER,0); | 1394 set_ireg(RET_REGISTER,0); |
1395 if (creg!=to) { | 1395 if (creg!=to) { |
1396 free_register(to); to = creg; | 1396 free_register(to); to = creg; |
1397 } | 1397 } |
1398 break; | 1398 break; |
1399 } | 1399 } |
1400 if (value) { | 1400 if (value) { |
1401 /* creg must point top of the destination data */ | 1401 /* creg must point top of the destination data */ |
1402 /* this code is necessary for the value of assignment or function call */ | 1402 /* this code is necessary for the value of assignment or function call */ |
1403 /* otherwise we don't need this */ | 1403 /* otherwise we don't need this */ |
1404 if(creg!=to) { | 1404 if(creg!=to) { |
1405 free_register(creg); creg=to; | 1405 free_register(creg); creg=to; |
1406 } | 1406 } |
1407 } | 1407 } |
1408 // free_register(dreg); | 1408 // free_register(dreg); |
1409 } | 1409 } |
1410 | 1410 |
1411 int | 1411 int |
1425 on_register = 0; | 1425 on_register = 0; |
1426 arg_reg = (arg_disp-ARG_LVAR_OFFSET)/SIZE_OF_INT + 1; | 1426 arg_reg = (arg_disp-ARG_LVAR_OFFSET)/SIZE_OF_INT + 1; |
1427 while (length>0 && | 1427 while (length>0 && |
1428 arg_disp>=ARG_LVAR_OFFSET && | 1428 arg_disp>=ARG_LVAR_OFFSET && |
1429 CALLER_ARG(arg_disp-ARG_LVAR_OFFSET)<0) { | 1429 CALLER_ARG(arg_disp-ARG_LVAR_OFFSET)<0) { |
1430 /* some part will be on registers */ | 1430 /* some part will be on registers */ |
1431 on_register ++; | 1431 on_register ++; |
1432 length-=SIZE_OF_INT; arg_disp+= SIZE_OF_INT; | 1432 length-=SIZE_OF_INT; arg_disp+= SIZE_OF_INT; |
1433 } | 1433 } |
1434 if (length>0) { | 1434 if (length>0) { |
1435 dreg = get_register(); if (!dreg) error(-1); | 1435 dreg = get_register(); if (!dreg) error(-1); |
1436 drn = register_name(dreg); | 1436 drn = register_name(dreg); |
1437 if (length<MAX_COPY_LEN) { | 1437 if (length<MAX_COPY_LEN) { |
1438 sreg = get_register(); if (!sreg) error(-1); | 1438 sreg = get_register(); if (!sreg) error(-1); |
1439 srn = register_name(sreg); | 1439 srn = register_name(sreg); |
1440 code_lvar(arg_disp,dreg); | 1440 code_lvar(arg_disp,dreg); |
1441 for(count=0;count<length;count+=SIZE_OF_INT) { | 1441 for(count=0;count<length;count+=SIZE_OF_INT) { |
1442 printf("\tlqd\t%s, %d(%s)\n",srn,count+on_register*SIZE_OF_INT,crn); | 1442 printf("\tlqd\t%s, %d(%s)\n",srn,count+on_register*SIZE_OF_INT,crn); |
1443 printf("\tstqd\t%s, %d(%s)\n",srn,count,drn); | 1443 printf("\tstqd\t%s, %d(%s)\n",srn,count,drn); |
1444 } | 1444 } |
1445 free_register(sreg); | 1445 free_register(sreg); |
1446 if (on_register) { | 1446 if (on_register) { |
1447 if (creg<=MAX_INPUT_REGISTER_VAR) { | 1447 if (creg<=MAX_INPUT_REGISTER_VAR) { |
1448 code_register(creg,REG_ip); | 1448 code_register(creg,REG_ip); |
1449 crn = register_name(REG_ip); | 1449 crn = register_name(REG_ip); |
1450 } | 1450 } |
1451 } | 1451 } |
1452 } else { | 1452 } else { |
1453 code_lvar(arg_disp,dreg); | 1453 code_lvar(arg_disp,dreg); |
1454 /* downward direction copy */ | 1454 /* downward direction copy */ |
1455 if (on_register) { | 1455 if (on_register) { |
1456 sreg = new_lvar(SIZE_OF_INT); | 1456 sreg = new_lvar(SIZE_OF_INT); |
1457 code_assign_lvar(sreg*4,creg,0); | 1457 code_assign_lvar(sreg*4,creg,0); |
1458 code_add(creg,on_register*SIZE_OF_INT,creg); | 1458 code_add(creg,on_register*SIZE_OF_INT,creg); |
1459 emit_copy(creg,dreg,length,0,0,1); | 1459 emit_copy(creg,dreg,length,0,0,1); |
1460 code_rlvar(sreg,REG_ip); | 1460 code_rlvar(sreg,REG_ip); |
1461 crn = register_name(REG_ip); | 1461 crn = register_name(REG_ip); |
1462 free_lvar(sreg); | 1462 free_lvar(sreg); |
1463 } else { | 1463 } else { |
1464 emit_copy(creg,dreg,length,0,0,1); | 1464 emit_copy(creg,dreg,length,0,0,1); |
1465 } | 1465 } |
1466 } | 1466 } |
1467 if (dreg!=-1) free_register(dreg); | 1467 if (dreg!=-1) free_register(dreg); |
1468 } | 1468 } |
1469 for (count=0,arg_reg; on_register-->0; arg_reg++,count+=SIZE_OF_INT) { | 1469 for (count=0,arg_reg; on_register-->0; arg_reg++,count+=SIZE_OF_INT) { |
1470 // len0 = (len0>2)?0:len0; | 1470 // len0 = (len0>2)?0:len0; |
1471 printf("\t%s\t%s, %d(%s)\n", cload(0,0), | 1471 printf("\t%s\t%s, %d(%s)\n", cload(0,0), |
1472 register_name(arg_reg), count,crn); | 1472 register_name(arg_reg), count,crn); |
1473 use_input_reg(arg_reg,1); | 1473 use_input_reg(arg_reg,1); |
1474 } | 1474 } |
1475 return length/SIZE_OF_INT; | 1475 return length/SIZE_OF_INT; |
1476 } | 1476 } |
1477 | 1477 |
1478 static void | 1478 static void |
1479 set_ireg(int reg,int mode) | 1479 set_ireg(int reg,int mode) |
1480 { | 1480 { |
1481 if (reg!=creg) { | 1481 if (reg!=creg) { |
1482 clear_ptr_cache_reg(reg); | 1482 clear_ptr_cache_reg(reg); |
1483 if (creg && reg!=creg ) { | 1483 if (creg && reg!=creg ) { |
1484 if (mode) { | 1484 if (mode) { |
1485 printf("\tori\t%s, %s, 0\n", | 1485 printf("\tori\t%s, %s, 0\n", |
1486 register_name(reg),register_name(creg)); | 1486 register_name(reg),register_name(creg)); |
1487 } | 1487 } |
1488 } | 1488 } |
1489 free_register(creg); | 1489 free_register(creg); |
1490 regs[reg]=USING_REG; | 1490 regs[reg]=USING_REG; |
1491 } | 1491 } |
1492 creg = reg; | 1492 creg = reg; |
1493 } | 1493 } |
1494 | 1494 |
1495 void | 1495 void |
1496 use_reg(int arg) | 1496 use_reg(int arg) |
1497 { | 1497 { |
1498 if (arg<0||arg> REGS_MAX) | 1498 if (arg<0||arg> REGS_MAX) |
1499 error(-1); | 1499 error(-1); |
1500 clear_ptr_cache_reg(arg); | 1500 clear_ptr_cache_reg(arg); |
1501 regs[arg]=USING_REG; | 1501 regs[arg]=USING_REG; |
1502 } | 1502 } |
1503 | 1503 |
1504 void | 1504 void |
1513 int reg_var = 0; | 1513 int reg_var = 0; |
1514 int len; | 1514 int len; |
1515 arg_on_register = 0; | 1515 arg_on_register = 0; |
1516 | 1516 |
1517 for(args = fnptr->dsp;args;args = cadr(args)) { | 1517 for(args = fnptr->dsp;args;args = cadr(args)) { |
1518 n = ncadddr(args); | 1518 n = ncadddr(args); |
1519 tag = n->sc; | 1519 tag = n->sc; |
1520 reg = n->dsp; | 1520 reg = n->dsp; |
1521 if (!n||n==&null_nptr) error(REG_ERR); | 1521 if (!n||n==&null_nptr) error(REG_ERR); |
1522 if (reg_var<MAX_INPUT_REGISTER_VAR) { | 1522 if (reg_var<MAX_INPUT_REGISTER_VAR) { |
1523 n->dsp = offset; | 1523 n->dsp = offset; |
1524 n->sc = LVAR; | 1524 n->sc = LVAR; |
1525 len = size(n->ty); len = round4(len); | 1525 len = size(n->ty); len = round4(len); |
1526 for(;len>0 && reg_var<MAX_INPUT_REGISTER_VAR;len-=SIZE_OF_INT) { | 1526 for(;len>0 && reg_var<MAX_INPUT_REGISTER_VAR;len-=SIZE_OF_INT) { |
1527 reg_var++; | 1527 reg_var++; |
1528 g_expr_u(assign_expr0(list3n(LVAR,offset,0), | 1528 g_expr_u(assign_expr0(list3n(LVAR,offset,0), |
1529 list3(REGISTER,reg_var,0),INT,INT)); | 1529 list3(REGISTER,reg_var,0),INT,INT)); |
1530 arg_on_register += SIZE_OF_INT; | 1530 arg_on_register += SIZE_OF_INT; |
1531 free_register(reg); | 1531 free_register(reg); |
1532 offset += SIZE_OF_INT; | 1532 offset += SIZE_OF_INT; |
1533 } | 1533 } |
1534 } | 1534 } |
1535 } | 1535 } |
1536 if (dots) { | 1536 if (dots) { |
1537 while ((reg = get_input_register_var(reg_var,0,0))) { | 1537 while ((reg = get_input_register_var(reg_var,0,0))) { |
1538 g_expr_u(assign_expr0( | 1538 g_expr_u(assign_expr0( |
1539 list3n(LVAR,offset,0),reg,INT,INT)); | 1539 list3n(LVAR,offset,0),reg,INT,INT)); |
1540 offset+=SIZE_OF_INT; | 1540 offset+=SIZE_OF_INT; |
1541 reg_var++; | 1541 reg_var++; |
1542 arg_on_register += SIZE_OF_INT; | 1542 arg_on_register += SIZE_OF_INT; |
1543 } | 1543 } |
1544 } | 1544 } |
1545 my_func_args = offset; | 1545 my_func_args = offset; |
1546 } | 1546 } |
1547 | 1547 |
1548 int | 1548 int |
1549 not_simple_p(int e3) | 1549 not_simple_p(int e3) |
1550 { | 1550 { |
1551 switch(e3) { | 1551 switch(e3) { |
1552 case FUNCTION: case CONV: case STASS: case ALLOCA: | 1552 case FUNCTION: case CONV: case STASS: case ALLOCA: |
1553 case DIV : case UDIV : case MOD : case UMOD : | 1553 case DIV : case UDIV : case MOD : case UMOD : |
1554 case LDIV: case LUDIV: case LMOD: case LUMOD: | 1554 case LDIV: case LUDIV: case LMOD: case LUMOD: |
1555 case LMUL: case LUMUL: | 1555 case LMUL: case LUMUL: |
1556 case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: | 1556 case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: |
1557 case DDIV: case DADD: case DSUB: case DMUL: case DMINUS: | 1557 case DDIV: case DADD: case DSUB: case DMUL: case DMINUS: |
1558 case DPOSTINC : case DPREINC : case DASSOP : | 1558 case DPOSTINC : case DPREINC : case DASSOP : |
1559 case DOP+LT : case DOP+LE : case DOP+GT : case DOP+GE : | 1559 case DOP+LT : case DOP+LE : case DOP+GT : case DOP+GE : |
1560 case DOP+EQ : case DOP+NEQ: | 1560 case DOP+EQ : case DOP+NEQ: |
1561 case RBIT_FIELD: case BASS: case BASSOP: case LCALL: | 1561 case RBIT_FIELD: case BASS: case BASSOP: case LCALL: |
1562 case INLINE: | 1562 case INLINE: |
1563 return 1; | 1563 return 1; |
1564 } | 1564 } |
1565 return 0; | 1565 return 0; |
1566 } | 1566 } |
1567 | 1567 |
1568 int | 1568 int |
1584 | 1584 |
1585 static void | 1585 static void |
1586 use_input_reg(int reg,int mode) | 1586 use_input_reg(int reg,int mode) |
1587 { | 1587 { |
1588 if (creg&® == creg) { | 1588 if (creg&® == creg) { |
1589 creg = 0; | 1589 creg = 0; |
1590 } | 1590 } |
1591 if (mode) use_reg(reg); | 1591 if (mode) use_reg(reg); |
1592 } | 1592 } |
1593 | 1593 |
1594 static int | 1594 static int |
1595 compute_complex_arg(int e3,int reg_arg_list,int arg) { | 1595 compute_complex_arg(int e3,int reg_arg_list,int arg) { |
1596 int t=caddr(e3); | 1596 int t=caddr(e3); |
1597 int e4 = car(e3); | 1597 int e4 = car(e3); |
1598 reg_arg_list = list2(arg,reg_arg_list); | 1598 reg_arg_list = list2(arg,reg_arg_list); |
1599 if (car(arg)==REGISTER||car(arg)==DREGISTER|| | 1599 if (car(arg)==REGISTER||car(arg)==DREGISTER|| |
1600 car(arg)==FREGISTER||car(arg)==LREGISTER) | 1600 car(arg)==FREGISTER||car(arg)==LREGISTER) |
1601 use_input_reg(cadr(arg),1); | 1601 use_input_reg(cadr(arg),1); |
1602 g_expr_u(assign_expr0(arg,e4,t,t)); | 1602 g_expr_u(assign_expr0(arg,e4,t,t)); |
1603 car(e3) = arg; | 1603 car(e3) = arg; |
1604 return reg_arg_list; | 1604 return reg_arg_list; |
1605 } | 1605 } |
1606 | 1606 |
1618 | 1618 |
1619 static int | 1619 static int |
1620 get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg) | 1620 get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg) |
1621 { | 1621 { |
1622 if(scalar(t)) { | 1622 if(scalar(t)) { |
1623 if (mode==AS_SAVE) { | 1623 if (mode==AS_SAVE) { |
1624 return get_register_var(0); | 1624 return get_register_var(0); |
1625 } else if (reg_arg+1>MAX_INPUT_REGISTER_VAR) { | 1625 } else if (reg_arg+1>MAX_INPUT_REGISTER_VAR) { |
1626 return list3n(LVAR,caller_arg_offset_v(nargs),0); | 1626 return list3n(LVAR,caller_arg_offset_v(nargs),0); |
1627 } else | 1627 } else |
1628 return get_input_register_var(reg_arg,0,0); | 1628 return get_input_register_var(reg_arg,0,0); |
1629 } else if (t==LONGLONG||t==ULONGLONG) { | 1629 } else if (t==LONGLONG||t==ULONGLONG) { |
1630 if (mode==AS_SAVE) { | 1630 if (mode==AS_SAVE) { |
1631 return get_lregister_var(0); | 1631 return get_lregister_var(0); |
1632 } else if (reg_arg>=MAX_INPUT_REGISTER_VAR) { | 1632 } else if (reg_arg>=MAX_INPUT_REGISTER_VAR) { |
1633 return list3n(LVAR,caller_arg_offset_v(nargs),0); | 1633 return list3n(LVAR,caller_arg_offset_v(nargs),0); |
1634 } else | 1634 } else |
1635 return get_input_lregister_var(reg_arg,0,0); | 1635 return get_input_lregister_var(reg_arg,0,0); |
1636 } else if (t==FLOAT) { | 1636 } else if (t==FLOAT) { |
1637 if (mode==AS_SAVE) { | 1637 if (mode==AS_SAVE) { |
1638 return get_dregister_var(0,0); | 1638 return get_dregister_var(0,0); |
1639 } else if (reg_arg>=MAX_INPUT_REGISTER_VAR) { | 1639 } else if (reg_arg>=MAX_INPUT_REGISTER_VAR) { |
1640 return list3n(LVAR,caller_arg_offset_v(nargs),0); | 1640 return list3n(LVAR,caller_arg_offset_v(nargs),0); |
1641 } else | 1641 } else |
1642 return get_input_dregister_var(freg_arg,0,0,0); | 1642 return get_input_dregister_var(freg_arg,0,0,0); |
1643 } else if (t==DOUBLE) { | 1643 } else if (t==DOUBLE) { |
1644 if (mode==AS_SAVE) { | 1644 if (mode==AS_SAVE) { |
1645 return get_dregister_var(0,1); | 1645 return get_dregister_var(0,1); |
1646 } else if (reg_arg>=MAX_INPUT_DREGISTER_VAR) { | 1646 } else if (reg_arg>=MAX_INPUT_DREGISTER_VAR) { |
1647 return list3n(LVAR,caller_arg_offset_v(nargs),0); | 1647 return list3n(LVAR,caller_arg_offset_v(nargs),0); |
1648 } else | 1648 } else |
1649 return get_input_dregister_var(reg_arg,0,0,1); | 1649 return get_input_dregister_var(reg_arg,0,0,1); |
1650 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { | 1650 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { |
1651 // 16byte もあるんだから、ほとんどの構造体は、レジスタに | 1651 // 16byte もあるんだから、ほとんどの構造体は、レジスタに |
1652 // 乗ってしまうらしい。なので、レジスタに乗っている前提の | 1652 // 乗ってしまうらしい。なので、レジスタに乗っている前提の |
1653 // コードを書いた方が良いらしい... | 1653 // コードを書いた方が良いらしい... |
1654 // でも、strop を書き直さないと出来ない | 1654 // でも、strop を書き直さないと出来ない |
1655 if (mode==AS_SAVE) { | 1655 if (mode==AS_SAVE) { |
1656 return get_register_var(0); | 1656 return get_register_var(0); |
1657 } else | 1657 } else |
1658 return list3n(LVAR,caller_arg_offset_v(nargs),0); | 1658 return list3n(LVAR,caller_arg_offset_v(nargs),0); |
1659 } else { | 1659 } else { |
1660 error(-1); | 1660 error(-1); |
1661 return get_register_var(0); | 1661 return get_register_var(0); |
1662 } | 1662 } |
1663 } | 1663 } |
1664 | 1664 |
1665 static void | 1665 static void |
1666 code_call(int e2,NMTBL *fn,int jmp) | 1666 code_call(int e2,NMTBL *fn,int jmp) |
1667 { | 1667 { |
1668 if (car(e2) == FNAME) { | 1668 if (car(e2) == FNAME) { |
1669 printf("\tbrsl\t$lr,%s\n",fn->nm); | 1669 printf("\tbrsl\t$lr,%s\n",fn->nm); |
1670 } else { | 1670 } else { |
1671 //printf("\tmov\tlr, pc\n"); | 1671 //printf("\tmov\tlr, pc\n"); |
1672 printf("\tori\t$sp,%s,0\n",register_name(cadr(jmp))); | 1672 printf("\tori\t$sp,%s,0\n",register_name(cadr(jmp))); |
1673 printf("\tori\t$sp, %s,0\n",register_name(cadr(jmp))); | 1673 printf("\tori\t$sp, %s,0\n",register_name(cadr(jmp))); |
1674 } | 1674 } |
1675 } | 1675 } |
1676 | 1676 |
1677 int | 1677 int |
1678 function(int e1) | 1678 function(int e1) |
1692 ret_type = function_type(cadddr(e1),&dots); | 1692 ret_type = function_type(cadddr(e1),&dots); |
1693 if (caddr(cadddr(e1))==0) dots=1; | 1693 if (caddr(cadddr(e1))==0) dots=1; |
1694 | 1694 |
1695 arg_assign = 0; | 1695 arg_assign = 0; |
1696 e2 = cadr(e1); | 1696 e2 = cadr(e1); |
1697 if (car(e2) == FNAME) { | 1697 if (car(e2) == FNAME) { |
1698 fn=ncaddr(e2); | 1698 fn=ncaddr(e2); |
1699 } else { | 1699 } else { |
1700 if (car(e2)==INDIRECT) e2=cadr(e2); // (*func)(i) case | 1700 if (car(e2)==INDIRECT) e2=cadr(e2); // (*func)(i) case |
1701 // jmp = get_register_var(0); | 1701 // jmp = get_register_var(0); |
1702 jmp = list2(REGISTER,REG_ip); | 1702 jmp = list2(REGISTER,REG_ip); |
1703 if (!simple_arg(e2)) { | 1703 if (!simple_arg(e2)) { |
1704 e3=get_register_var(0); | 1704 e3=get_register_var(0); |
1705 reg_arg_list = list2(e3,reg_arg_list); | 1705 reg_arg_list = list2(e3,reg_arg_list); |
1706 g_expr_u(assign_expr0(e3,e2,INT,INT)); | 1706 g_expr_u(assign_expr0(e3,e2,INT,INT)); |
1707 e2=e3; | 1707 e2=e3; |
1708 } | 1708 } |
1709 reg_arg_list = list2(jmp,reg_arg_list); | 1709 reg_arg_list = list2(jmp,reg_arg_list); |
1710 arg_assign = list2(assign_expr0(jmp,e2,INT,INT),arg_assign); | 1710 arg_assign = list2(assign_expr0(jmp,e2,INT,INT),arg_assign); |
1711 } | 1711 } |
1712 /* First we execute complex argument to avoid interaction with | 1712 /* First we execute complex argument to avoid interaction with |
1713 input variables. Remain the last complex argument in complex_. */ | 1713 input variables. Remain the last complex argument in complex_. */ |
1714 stargs = 0; | 1714 stargs = 0; |
1715 complex_ = 0; | 1715 complex_ = 0; |
1716 nargs = reg_arg = freg_arg = 0; | 1716 nargs = reg_arg = freg_arg = 0; |
1717 pnargs = preg_arg = pfreg_arg = 0; | 1717 pnargs = preg_arg = pfreg_arg = 0; |
1718 for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { | 1718 for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { |
1719 t=caddr(e3); | 1719 t=caddr(e3); |
1720 if (reg_arg==3 && (t==DOUBLE||t==LONGLONG||t==ULONGLONG)) { | 1720 if (reg_arg==3 && (t==DOUBLE||t==LONGLONG||t==ULONGLONG)) { |
1721 half_register=1; | 1721 half_register=1; |
1722 } | 1722 } |
1723 if ((e5= !simple_arg(car(e3)))) { | 1723 if ((e5= !simple_arg(car(e3)))) { |
1724 if (complex_) { | 1724 if (complex_) { |
1725 arg = get_input_arg(caddr(complex_),AS_SAVE, | 1725 arg = get_input_arg(caddr(complex_),AS_SAVE, |
1726 pnargs,preg_arg,pfreg_arg); | 1726 pnargs,preg_arg,pfreg_arg); |
1727 reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg); | 1727 reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg); |
1728 } | 1728 } |
1729 // memorise last complex arg parameter | 1729 // memorise last complex arg parameter |
1730 pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg; | 1730 pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg; |
1731 complex_ = e3; | 1731 complex_ = e3; |
1732 } | 1732 } |
1733 if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { | 1733 if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { |
1734 // The struct should be pushed after complex arguments. | 1734 // The struct should be pushed after complex arguments. |
1735 if (e5) { // compute address only, complex_ is me now. Clear it. | 1735 if (e5) { // compute address only, complex_ is me now. Clear it. |
1736 complex_ = 0; | 1736 complex_ = 0; |
1737 e4 = car(e3); | 1737 e4 = car(e3); |
1738 if (car(e4)==RSTRUCT) e4 = cadr(e4); | 1738 if (car(e4)==RSTRUCT) e4 = cadr(e4); |
1739 if (!simple_arg(cadr(e4))) { | 1739 if (!simple_arg(cadr(e4))) { |
1740 // Calculate complex struct address here. | 1740 // Calculate complex struct address here. |
1741 // If simple, leave it. | 1741 // If simple, leave it. |
1742 arg = get_register_var(0); | 1742 arg = get_register_var(0); |
1743 g_expr_u(assign_expr0(arg,e4,INT,INT)); | 1743 g_expr_u(assign_expr0(arg,e4,INT,INT)); |
1744 car(e3)=arg; | 1744 car(e3)=arg; |
1745 reg_arg_list = list2(arg,reg_arg_list); | 1745 reg_arg_list = list2(arg,reg_arg_list); |
1746 if (car(arg)==REGISTER) use_input_reg(cadr(arg),1); | 1746 if (car(arg)==REGISTER) use_input_reg(cadr(arg),1); |
1747 else car(e3) = rvalue_t(arg,INT); | 1747 else car(e3) = rvalue_t(arg,INT); |
1748 } | 1748 } |
1749 } | 1749 } |
1750 stargs = list4(e3,stargs,nargs,reg_arg); | 1750 stargs = list4(e3,stargs,nargs,reg_arg); |
1751 } | 1751 } |
1752 increment_function_arg(e3,&nargs,®_arg,&freg_arg); | 1752 increment_function_arg(e3,&nargs,®_arg,&freg_arg); |
1753 } | 1753 } |
1754 | 1754 |
1755 /* now all input register vars are free */ | 1755 /* now all input register vars are free */ |
1756 code_save_stacks(); | 1756 code_save_stacks(); |
1757 set_ireg(CREG_REGISTER,0); | 1757 set_ireg(CREG_REGISTER,0); |
1761 // We cannot do this in the previous loop, because the copied struct may be | 1761 // We cannot do this in the previous loop, because the copied struct may be |
1762 // override by other complex arguments. But before this we have to check | 1762 // override by other complex arguments. But before this we have to check |
1763 // complex_. | 1763 // complex_. |
1764 | 1764 |
1765 if (stargs) { | 1765 if (stargs) { |
1766 if (complex_) { | 1766 if (complex_) { |
1767 arg = get_input_arg(caddr(complex_),AS_SAVE, | 1767 arg = get_input_arg(caddr(complex_),AS_SAVE, |
1768 pnargs,preg_arg,pfreg_arg); | 1768 pnargs,preg_arg,pfreg_arg); |
1769 reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg); | 1769 reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg); |
1770 } | 1770 } |
1771 for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) { | 1771 for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) { |
1772 e3 = car(stargs); | 1772 e3 = car(stargs); |
1773 e4 = car(e3); | 1773 e4 = car(e3); |
1774 t = caddr(e3); | 1774 t = caddr(e3); |
1775 arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0); | 1775 arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0); |
1776 push_struct(e4,t,arg); | 1776 push_struct(e4,t,arg); |
1777 car(e3)=0; // done | 1777 car(e3)=0; // done |
1778 if (car(arg)==REGISTER) // wrong? | 1778 if (car(arg)==REGISTER) // wrong? |
1779 use_input_reg(cadr(arg),1); | 1779 use_input_reg(cadr(arg),1); |
1780 } | 1780 } |
1781 } else { | 1781 } else { |
1782 // last complex argument can use input register | 1782 // last complex argument can use input register |
1783 if (complex_) { | 1783 if (complex_) { |
1784 arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg); | 1784 arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg); |
1785 reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg); | 1785 reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg); |
1786 if (car(arg)!=LVAR) use_input_reg(cadr(arg),1); | 1786 if (car(arg)!=LVAR) use_input_reg(cadr(arg),1); |
1787 car(complex_) = 0; // done. | 1787 car(complex_) = 0; // done. |
1788 if (car(arg)==REGISTER) | 1788 if (car(arg)==REGISTER) |
1789 use_input_reg(cadr(arg),1); | 1789 use_input_reg(cadr(arg),1); |
1790 } | 1790 } |
1791 } | 1791 } |
1792 | 1792 |
1793 nargs = reg_arg = freg_arg = 0; | 1793 nargs = reg_arg = freg_arg = 0; |
1794 // calc stack arguments first, it may requires extra registers, | 1794 // calc stack arguments first, it may requires extra registers, |
1795 // and we can still use input registers now. | 1795 // and we can still use input registers now. |
1796 for (e3 = e1; e3; | 1796 for (e3 = e1; e3; |
1797 increment_function_arg(e3,&nargs,®_arg,&freg_arg), | 1797 increment_function_arg(e3,&nargs,®_arg,&freg_arg), |
1798 e3 = cadr(e3)) { | 1798 e3 = cadr(e3)) { |
1799 if (!(e4=car(e3))) continue; | 1799 if (!(e4=car(e3))) continue; |
1800 t=caddr(e3); | 1800 t=caddr(e3); |
1801 arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg); | 1801 arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg); |
1802 if (car(arg)!=LVAR) continue; | 1802 if (car(arg)!=LVAR) continue; |
1803 g_expr_u(assign_expr0(arg,e4,t,t)); | 1803 g_expr_u(assign_expr0(arg,e4,t,t)); |
1804 car(e3)=0; // done | 1804 car(e3)=0; // done |
1805 } | 1805 } |
1806 if (half_register) { | 1806 if (half_register) { |
1807 // half register case writes *(sp-1) but it will be Ok. | 1807 // half register case writes *(sp-1) but it will be Ok. |
1808 if (max_func_args<4) max_func_args=4; | 1808 if (max_func_args<4) max_func_args=4; |
1809 g_expr_u(assign_expr0(list3(REGISTER,4,0), | 1809 g_expr_u(assign_expr0(list3(REGISTER,4,0), |
1810 list3n(LVAR,caller_arg_offset_v(3),0),INT,INT)); | 1810 list3n(LVAR,caller_arg_offset_v(3),0),INT,INT)); |
1811 use_input_reg(4,1); | 1811 use_input_reg(4,1); |
1812 } | 1812 } |
1813 nargs = reg_arg = freg_arg = 0; | 1813 nargs = reg_arg = freg_arg = 0; |
1814 for (e3 = e1; e3; | 1814 for (e3 = e1; e3; |
1815 increment_function_arg(e3,&nargs,®_arg,&freg_arg), | 1815 increment_function_arg(e3,&nargs,®_arg,&freg_arg), |
1816 e3 = cadr(e3)) { | 1816 e3 = cadr(e3)) { |
1817 if (!(e4=car(e3))) continue; | 1817 if (!(e4=car(e3))) continue; |
1818 t=caddr(e3); | 1818 t=caddr(e3); |
1819 arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg); | 1819 arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg); |
1820 if(scalar(t)) { | 1820 if(scalar(t)) { |
1821 reg_arg_list = list2(arg,reg_arg_list); | 1821 reg_arg_list = list2(arg,reg_arg_list); |
1822 /* protect from input register free */ | 1822 /* protect from input register free */ |
1823 if (car(arg)==REGISTER) | 1823 if (car(arg)==REGISTER) |
1824 use_input_reg(cadr(arg),1); | 1824 use_input_reg(cadr(arg),1); |
1825 g_expr_u(assign_expr0(arg,e4,t,t)); | 1825 g_expr_u(assign_expr0(arg,e4,t,t)); |
1826 } else if (t==LONGLONG||t==ULONGLONG) { | 1826 } else if (t==LONGLONG||t==ULONGLONG) { |
1827 if (car(arg)==LREGISTER) { | 1827 if (car(arg)==LREGISTER) { |
1828 use_input_reg(cadr(arg),1); | 1828 use_input_reg(cadr(arg),1); |
1829 } | 1829 } |
1830 reg_arg_list = list2(arg,reg_arg_list); | 1830 reg_arg_list = list2(arg,reg_arg_list); |
1831 g_expr_u(assign_expr0(arg,e4,t,t)); | 1831 g_expr_u(assign_expr0(arg,e4,t,t)); |
1832 } else if (t==DOUBLE) { | 1832 } else if (t==DOUBLE) { |
1833 reg_arg_list = list2(arg,reg_arg_list); | 1833 reg_arg_list = list2(arg,reg_arg_list); |
1834 if (car(arg)==REGISTER) { | 1834 if (car(arg)==REGISTER) { |
1835 use_input_reg(cadr(arg),1); | 1835 use_input_reg(cadr(arg),1); |
1836 | 1836 |
1837 | 1837 |
1838 } else { | 1838 } else { |
1839 g_expr_u(assign_expr0(arg,e4,t,t)); | 1839 g_expr_u(assign_expr0(arg,e4,t,t)); |
1840 } | 1840 } |
1841 } else if (t==FLOAT) { | 1841 } else if (t==FLOAT) { |
1842 reg_arg_list = list2(arg,reg_arg_list); | 1842 reg_arg_list = list2(arg,reg_arg_list); |
1843 if (car(arg)==REGISTER) { | 1843 if (car(arg)==REGISTER) { |
1844 use_input_reg(cadr(arg),1);/* protect from input register free */ | 1844 use_input_reg(cadr(arg),1);/* protect from input register free */ |
1845 | 1845 |
1846 } else { | 1846 } else { |
1847 g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ | 1847 g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ |
1848 } | 1848 } |
1849 } | 1849 } |
1850 // structs are finished | 1850 // structs are finished |
1851 } | 1851 } |
1852 if (max_func_args<nargs) max_func_args=nargs; | 1852 if (max_func_args<nargs) max_func_args=nargs; |
1853 for(;arg_assign;arg_assign=cadr(arg_assign)) { | 1853 for(;arg_assign;arg_assign=cadr(arg_assign)) { |
1854 g_expr_u(car(arg_assign)); | 1854 g_expr_u(car(arg_assign)); |
1855 } | 1855 } |
1856 clear_ptr_cache(); | 1856 clear_ptr_cache(); |
1857 code_call(e2,fn,jmp); | 1857 code_call(e2,fn,jmp); |
1858 free_register_var(reg_arg_list); | 1858 free_register_var(reg_arg_list); |
1859 for(i=1;i<MAX_INPUT_REGISTER_VAR;i++) { | 1859 for(i=1;i<MAX_INPUT_REGISTER_VAR;i++) { |
1860 free_register(i); | 1860 free_register(i); |
1861 } | 1861 } |
1862 if (ret_type!=VOID) { | 1862 if (ret_type!=VOID) { |
1863 set_ireg(RET_REGISTER,0); | 1863 set_ireg(RET_REGISTER,0); |
1864 use_reg(RET_REGISTER); | 1864 use_reg(RET_REGISTER); |
1865 } else { | 1865 } else { |
1895 | 1895 |
1896 void | 1896 void |
1897 code_fix_frame_pointer(int env) { | 1897 code_fix_frame_pointer(int env) { |
1898 char *trn; | 1898 char *trn; |
1899 if (is_function(fnptr) && ! env) { | 1899 if (is_function(fnptr) && ! env) { |
1900 trn = register_name(REG_ip); | 1900 trn = register_name(REG_ip); |
1901 printf("\ta\t$sp, $sp, %s\n",trn); | 1901 printf("\ta\t$sp, $sp, %s\n",trn); |
1902 } | 1902 } |
1903 } | 1903 } |
1904 | 1904 |
1905 static void | 1905 static void |
1906 code_unfix_frame_pointer() | 1906 code_unfix_frame_pointer() |
1971 | 1971 |
1972 static void | 1972 static void |
1973 lmove(int to,int from) | 1973 lmove(int to,int from) |
1974 { | 1974 { |
1975 printf("\tori\t%s, %s, 0\n", | 1975 printf("\tori\t%s, %s, 0\n", |
1976 register_name(to),register_name(from)); | 1976 register_name(to),register_name(from)); |
1977 | 1977 |
1978 | 1978 |
1979 } | 1979 } |
1980 | 1980 |
1981 static void | 1981 static void |
2029 use_int(creg); | 2029 use_int(creg); |
2030 crn=register_name(creg); | 2030 crn=register_name(creg); |
2031 lvar_intro(e2); | 2031 lvar_intro(e2); |
2032 printf("\t%s\t%s,",cstore(byte),crn); | 2032 printf("\t%s\t%s,",cstore(byte),crn); |
2033 e2 *= 4; | 2033 e2 *= 4; |
2034 lvar(e2,""); | 2034 lvar(e2,""); |
2035 } | 2035 } |
2036 | 2036 |
2037 void | 2037 void |
2038 code_assign_register(int e2,int byte,int creg) { | 2038 code_assign_register(int e2,int byte,int creg) { |
2039 use_int(creg); | 2039 use_int(creg); |
2040 if (e2!=creg) { | 2040 if (e2!=creg) { |
2041 printf("\tori\t%s, %s, 0\n",register_name(e2),register_name(creg)); | 2041 printf("\tori\t%s, %s, 0\n",register_name(e2),register_name(creg)); |
2042 } | 2042 } |
2043 } | 2043 } |
2044 | 2044 |
2045 void | 2045 void |
2046 code_assign(int e2,int byte,int creg) { | 2046 code_assign(int e2,int byte,int creg) { |
2096 char *orn,*crn; | 2096 char *orn,*crn; |
2097 // creg = creg op oreg | 2097 // creg = creg op oreg |
2098 | 2098 |
2099 use_int(creg); | 2099 use_int(creg); |
2100 if(oreg==-1) { | 2100 if(oreg==-1) { |
2101 error(-1); | 2101 error(-1); |
2102 } else if (oreg<= -REG_LVAR_OFFSET) { | 2102 } else if (oreg<= -REG_LVAR_OFFSET) { |
2103 ox = get_register(); if (ox<0) error(-1); | 2103 ox = get_register(); if (ox<0) error(-1); |
2104 code_rlvar(oreg+REG_LVAR_OFFSET,ox); | 2104 code_rlvar(oreg+REG_LVAR_OFFSET,ox); |
2105 free_lvar(oreg+REG_LVAR_OFFSET); | 2105 free_lvar(oreg+REG_LVAR_OFFSET); |
2106 oreg = ox; | 2106 oreg = ox; |
2107 } | 2107 } |
2108 | 2108 |
2109 switch(op) { | 2109 switch(op) { |
2110 case LSHIFT: | 2110 case LSHIFT: |
2111 case ULSHIFT: | 2111 case ULSHIFT: |
2112 shift("asl",creg,oreg); | 2112 shift("asl",creg,oreg); |
2113 if(ox!=-1) free_register(ox); | 2113 if(ox!=-1) free_register(ox); |
2114 return; | 2114 return; |
2115 case RSHIFT: | 2115 case RSHIFT: |
2116 shift("asr",creg,oreg); | 2116 shift("asr",creg,oreg); |
2117 if(ox!=-1) free_register(ox); | 2117 if(ox!=-1) free_register(ox); |
2118 return; | 2118 return; |
2119 case URSHIFT: | 2119 case URSHIFT: |
2120 shift("lsr",creg,oreg); | 2120 shift("lsr",creg,oreg); |
2121 if(ox!=-1) free_register(ox); | 2121 if(ox!=-1) free_register(ox); |
2122 return; | 2122 return; |
2123 } | 2123 } |
2124 orn = register_name(oreg); | 2124 orn = register_name(oreg); |
2125 crn = register_name(creg); | 2125 crn = register_name(creg); |
2126 switch(op) { | 2126 switch(op) { |
2127 case ADD: | 2127 case ADD: |
2128 printf("\ta\t%s, %s, %s\n",crn,crn,orn); | 2128 printf("\ta\t%s, %s, %s\n",crn,crn,orn); |
2129 break; | 2129 break; |
2130 case SUB: | 2130 case SUB: |
2131 printf("\tsf\t%s, %s, %s\n",crn,crn,orn); | 2131 printf("\tsf\t%s, %s, %s\n",crn,crn,orn); |
2132 break; | 2132 break; |
2133 case CMP: | 2133 case CMP: |
2134 printf("\tceqp\t%s, %s\n",crn,orn); | 2134 printf("\tceqp\t%s, %s\n",crn,orn); |
2135 break; | 2135 break; |
2136 case BAND: | 2136 case BAND: |
2137 printf("\tand\t%s, %s, %s\n",crn,crn,orn); | 2137 printf("\tand\t%s, %s, %s\n",crn,crn,orn); |
2138 break; | 2138 break; |
2139 case EOR: | 2139 case EOR: |
2140 printf("\txor\t%s, %s, %s\n",crn,crn,orn); | 2140 printf("\txor\t%s, %s, %s\n",crn,crn,orn); |
2141 break; | 2141 break; |
2142 case BOR: | 2142 case BOR: |
2143 printf("\tor\t%s, %s, %s\n",crn,crn,orn); | 2143 printf("\tor\t%s, %s, %s\n",crn,crn,orn); |
2144 break; | 2144 break; |
2145 case MUL: | 2145 case MUL: |
2146 case UMUL: | 2146 case UMUL: |
2147 /* target!=source */ | 2147 /* target!=source */ |
2148 printf("\tmpy\t%s, %s, %s\n",crn,orn,crn); | 2148 printf("\tmpy\t%s, %s, %s\n",crn,orn,crn); |
2149 break; | 2149 break; |
2150 case DIV: | 2150 case DIV: |
2151 code_int_lib("__divsi3",creg,oreg); break; | 2151 code_int_lib("__divsi3",creg,oreg); break; |
2152 case UDIV: | 2152 case UDIV: |
2153 code_int_lib("__udivsi3",creg,oreg); break; | 2153 code_int_lib("__udivsi3",creg,oreg); break; |
2154 case MOD: | 2154 case MOD: |
2155 code_int_lib("__modsi3",creg,oreg); break; | 2155 code_int_lib("__modsi3",creg,oreg); break; |
2156 case UMOD: | 2156 case UMOD: |
2157 code_int_lib("__umodsi3",creg,oreg); break; | 2157 code_int_lib("__umodsi3",creg,oreg); break; |
2158 default: | 2158 default: |
2159 error(-1); | 2159 error(-1); |
2160 } | 2160 } |
2161 if(ox!=-1) free_register(ox); | 2161 if(ox!=-1) free_register(ox); |
2162 } | 2162 } |
2163 | 2163 |
2164 int | 2164 int |
2166 { | 2166 { |
2167 if (car(v)!=CONST) return 0; | 2167 if (car(v)!=CONST) return 0; |
2168 v = cadr(v); | 2168 v = cadr(v); |
2169 switch(op) { | 2169 switch(op) { |
2170 case MUL: case UMUL: case DIV: case UDIV: | 2170 case MUL: case UMUL: case DIV: case UDIV: |
2171 return ilog(v); | 2171 return ilog(v); |
2172 case ADD: case SUB: | 2172 case ADD: case SUB: |
2173 return 1; | 2173 return 1; |
2174 case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT: | 2174 case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT: |
2175 return 0<v&&v<=32; | 2175 return 0<v&&v<=32; |
2176 case CMP: | 2176 case CMP: |
2177 return is_stage1_const(v,CMP); | 2177 return is_stage1_const(v,CMP); |
2178 case EOR: case BOR: case BAND: | 2178 case EOR: case BOR: case BAND: |
2179 return (is_stage1_const(v,0)>0); | 2179 return (is_stage1_const(v,0)>0); |
2180 default: | 2180 default: |
2181 return 0; | 2181 return 0; |
2182 } | 2182 } |
2183 } | 2183 } |
2184 | 2184 |
2185 void | 2185 void |
2186 oprtc(int op,int creg, int v) | 2186 oprtc(int op,int creg, int v) |
2190 crn = register_name(creg); | 2190 crn = register_name(creg); |
2191 v = cadr(v); | 2191 v = cadr(v); |
2192 | 2192 |
2193 switch(op) { | 2193 switch(op) { |
2194 case MUL: case UMUL: | 2194 case MUL: case UMUL: |
2195 v=ilog(v); | 2195 v=ilog(v); |
2196 case LSHIFT: | 2196 case LSHIFT: |
2197 case ULSHIFT: | 2197 case ULSHIFT: |
2198 printf("\troti\t%s, %s,-%d\n",crn,crn,v); | 2198 printf("\troti\t%s, %s,-%d\n",crn,crn,v); |
2199 break; | 2199 break; |
2200 case DIV: | 2200 case DIV: |
2201 v=ilog(v); | 2201 v=ilog(v); |
2202 case RSHIFT: | 2202 case RSHIFT: |
2203 printf("\troti\t%s, %s, -%d\n",crn,crn,v); | 2203 printf("\troti\t%s, %s, -%d\n",crn,crn,v); |
2204 break; | 2204 break; |
2205 case UDIV: | 2205 case UDIV: |
2206 v=ilog(v); | 2206 v=ilog(v); |
2207 case URSHIFT: | 2207 case URSHIFT: |
2208 printf("\tshli\t%s, %s,%d\n",crn,crn,v); | 2208 printf("\tshli\t%s, %s,%d\n",crn,crn,v); |
2209 break; | 2209 break; |
2210 case ADD: | 2210 case ADD: |
2211 code_add(creg,v,creg); | 2211 code_add(creg,v,creg); |
2212 break; | 2212 break; |
2213 case SUB: | 2213 case SUB: |
2214 code_add(creg,-v,creg); | 2214 code_add(creg,-v,creg); |
2215 break; | 2215 break; |
2216 case CMP: printf("\tceq\t%s,%d\n",crn,v); break; | 2216 case CMP: printf("\tceq\t%s,%d\n",crn,v); break; |
2217 case BOR: printf("\tori\t%s, %s, %d\n",crn,crn,v); break; | 2217 case BOR: printf("\tori\t%s, %s, %d\n",crn,crn,v); break; |
2218 case EOR: printf("\txori\t%s, %s, %d\n",crn,crn,v); break; | 2218 case EOR: printf("\txori\t%s, %s, %d\n",crn,crn,v); break; |
2219 case BAND: printf("\tandi\t%s, %s, %d\n",crn,crn,v); break; | 2219 case BAND: printf("\tandi\t%s, %s, %d\n",crn,crn,v); break; |
2220 default: | 2220 default: |
2221 error(-1); | 2221 error(-1); |
2222 } | 2222 } |
2223 } | 2223 } |
2224 | 2224 |
2225 void | 2225 void |
2226 shift(char *op, int creg, int reg) | 2226 shift(char *op, int creg, int reg) |
2228 char *crn; | 2228 char *crn; |
2229 char *rrn = register_name(reg); | 2229 char *rrn = register_name(reg); |
2230 use_int(creg); | 2230 use_int(creg); |
2231 crn = register_name(creg); | 2231 crn = register_name(creg); |
2232 if(crn == "asr") printf("\tshl\t%s, %s,%s\n",crn,crn,rrn); //算術右シフト | 2232 if(crn == "asr") printf("\tshl\t%s, %s,%s\n",crn,crn,rrn); //算術右シフト |
2233 if(crn == "asl") printf("\trotma\t%s, %s, -%s\n",crn,crn,rrn); //算術左シフト | 2233 if(crn == "asl") printf("\trotma\t%s, %s, -%s\n",crn,crn,rrn); //算術左シフト |
2234 if(crn == "lsr") printf("\trot\t%s, %s, %s\n",crn,crn,rrn); //左シフト | 2234 if(crn == "lsr") printf("\trot\t%s, %s, %s\n",crn,crn,rrn); //左シフト |
2235 //printf("\tmov\t%s, %s, %s %s\n",crn,crn,op,rrn); | 2235 //printf("\tmov\t%s, %s, %s %s\n",crn,crn,op,rrn); |
2236 } | 2236 } |
2237 | 2237 |
2238 void | 2238 void |
2239 ld_indexx(int byte, int n, int xreg,int creg, int sign) | 2239 ld_indexx(int byte, int n, int xreg,int creg, int sign) |
2240 { | 2240 { |
2241 use_int(creg); | 2241 use_int(creg); |
2242 code_ld(cload(byte,sign),creg,n,xreg,cext_at(byte,sign)); | 2242 code_ld(cload(byte,sign),creg,n,xreg,cext_at(byte,sign)); |
2243 } | 2243 } |
2244 | 2244 |
2245 int | 2245 int |
2256 int regsv; | 2256 int regsv; |
2257 char *rn,*crn; | 2257 char *rn,*crn; |
2258 crn = register_name(csreg); | 2258 crn = register_name(csreg); |
2259 | 2259 |
2260 if (!(sign=is_stage1_const(e,CMP))) { | 2260 if (!(sign=is_stage1_const(e,CMP))) { |
2261 regsv = regs[csreg]; regs[csreg]=1; | 2261 regsv = regs[csreg]; regs[csreg]=1; |
2262 rn = register_name(reg= get_register()); | 2262 rn = register_name(reg= get_register()); |
2263 regs[csreg] = regsv; | 2263 regs[csreg] = regsv; |
2264 code_const(e,reg); | 2264 code_const(e,reg); |
2265 printf("\tceq\t%s, %s, %s\n",crn,crn,rn); | 2265 printf("\tceq\t%s, %s, %s\n",crn,crn,rn); |
2266 } else { | 2266 } else { |
2267 if (sign>0) | 2267 if (sign>0) |
2268 printf("\tceqi\t%s, %s, %d\n",crn,crn,e); | 2268 printf("\tceqi\t%s, %s, %d\n",crn,crn,e); |
2269 else | 2269 else |
2270 //printf("\tcmn\t%s, #%d\n",crn,-e); | 2270 //printf("\tcmn\t%s, #%d\n",crn,-e); |
2271 printf("\tceqi\t%s, %s, %d\n",crn,crn,-e); | 2271 printf("\tceqi\t%s, %s, %d\n",crn,crn,-e); |
2272 } | 2272 } |
2273 switch(cond) { | 2273 switch(cond) { |
2274 case -1: break; | 2274 case -1: break; |
2275 case 1: | 2275 case 1: |
2276 printf("\tbr\t.LC%d\n",label); break; | 2276 printf("\tbr\t.LC%d\n",label); break; |
2277 case 0: | 2277 case 0: |
2278 printf("\tbr\t.LC%d\n",label); break; | 2278 printf("\tbr\t.LC%d\n",label); break; |
2279 case LT: | 2279 case LT: |
2280 printf("\tbra\t.LC%d\n",label); break; | 2280 printf("\tbra\t.LC%d\n",label); break; |
2281 case GT: | 2281 case GT: |
2282 printf("\tbgt\t.LC%d\n",label); break; | 2282 printf("\tbgt\t.LC%d\n",label); break; |
2283 default: error(-1); | 2283 default: error(-1); |
2284 } | 2284 } |
2285 if (reg!=-1) free_register(reg); | 2285 if (reg!=-1) free_register(reg); |
2286 } | 2286 } |
2287 | 2287 |
2312 char *rn1; | 2312 char *rn1; |
2313 char *rn0; | 2313 char *rn0; |
2314 char *cc=0,*ncc=0; | 2314 char *cc=0,*ncc=0; |
2315 | 2315 |
2316 if (mode==COND_BRANCH_CONST||mode==COND_VALUE_CONST) { | 2316 if (mode==COND_BRANCH_CONST||mode==COND_VALUE_CONST) { |
2317 rn1 = register_name(r1); | 2317 rn1 = register_name(r1); |
2318 if (r2>=0) | 2318 if (r2>=0) |
2319 printf("\tceqi\t%s, %s, %d\n",rn1,rn1,r2); | 2319 printf("\tceqi\t%s, %s, %d\n",rn1,rn1,r2); |
2320 else | 2320 else |
2321 printf("\tceqi\t%s, %s, -%d\n",rn1,rn1,-r2); | 2321 printf("\tceqi\t%s, %s, -%d\n",rn1,rn1,-r2); |
2322 } else { | 2322 } else { |
2323 rn1 = register_name(r1); | 2323 rn1 = register_name(r1); |
2324 rn2 = register_name(r2); | 2324 rn2 = register_name(r2); |
2325 printf("\tceq\t%s, %s, %s\n",rn1,rn1,rn2); | 2325 printf("\tceq\t%s, %s, %s\n",rn1,rn1,rn2); |
2326 } | 2326 } |
2327 | 2327 |
2328 switch(op+(!cond)*BNOT) { | 2328 switch(op+(!cond)*BNOT) { |
2329 case GT: case LE+BNOT: cc="r"; ncc="r"; break; | 2329 case GT: case LE+BNOT: cc="r"; ncc="r"; break; |
2330 case LE: case GT+BNOT: cc="r"; ncc="r"; break; | 2330 case LE: case GT+BNOT: cc="r"; ncc="r"; break; |
2331 case GE: case LT+BNOT: cc="r"; ncc="r"; break; | 2331 case GE: case LT+BNOT: cc="r"; ncc="r"; break; |
2332 case LT: case GE+BNOT: cc="r"; ncc="r"; break; | 2332 case LT: case GE+BNOT: cc="r"; ncc="r"; break; |
2333 case UGT: case ULE+BNOT: cc="r"; ncc="r"; break; | 2333 case UGT: case ULE+BNOT: cc="r"; ncc="r"; break; |
2334 case ULE: case UGT+BNOT: cc="r"; ncc="r"; break; | 2334 case ULE: case UGT+BNOT: cc="r"; ncc="r"; break; |
2335 case UGE: case ULT+BNOT: cc="r"; ncc="r"; break; | 2335 case UGE: case ULT+BNOT: cc="r"; ncc="r"; break; |
2336 case ULT: case UGE+BNOT: cc="r"; ncc="r"; break; | 2336 case ULT: case UGE+BNOT: cc="r"; ncc="r"; break; |
2337 case EQ: case NEQ+BNOT: cc="r"; ncc="r"; break; | 2337 case EQ: case NEQ+BNOT: cc="r"; ncc="r"; break; |
2338 //case NEQ: case EQ+BNOT: cc="rnz"; ncc="r"; break; | 2338 //case NEQ: case EQ+BNOT: cc="rnz"; ncc="r"; break; |
2339 case NEQ: case EQ+BNOT: cc="r"; ncc="r"; break; | 2339 case NEQ: case EQ+BNOT: cc="r"; ncc="r"; break; |
2340 default: error(-1); | 2340 default: error(-1); |
2341 } | 2341 } |
2342 | 2342 |
2343 if (mode==COND_BRANCH||mode==COND_BRANCH_CONST) { | 2343 if (mode==COND_BRANCH||mode==COND_BRANCH_CONST) { |
2344 printf("\tb%s\t.LC%d\n",cc,l1); | 2344 printf("\tb%s\t.LC%d\n",cc,l1); |
2345 //printf("\tb%s\t%s, .LC%d\n",cc,rn1,l1); | 2345 //printf("\tb%s\t%s, .LC%d\n",cc,rn1,l1); |
2346 } else if (mode==COND_VALUE||mode==COND_VALUE_CONST) { | 2346 } else if (mode==COND_VALUE||mode==COND_VALUE_CONST) { |
2347 rn0 = register_name(r0); | 2347 rn0 = register_name(r0); |
2348 // ここはnccで分岐させなきゃダメだな | 2348 // ここはnccで分岐させなきゃダメだな |
2349 printf("#####pcond##########\n"); | 2349 printf("#####pcond##########\n"); |
2350 //printf("\tmovhoge%s\t%s, #0\n",ncc,rn0); | 2350 //printf("\tmovhoge%s\t%s, #0\n",ncc,rn0); |
2351 //printf("\tmovfuho%s\t%s, #1\n",cc,rn0); | 2351 //printf("\tmovfuho%s\t%s, #1\n",cc,rn0); |
2352 } else error(-1); | 2352 } else error(-1); |
2353 } | 2353 } |
2354 | 2354 |
2355 int | 2355 int |
2356 rexpr_bool(int e1, int reg) | 2356 rexpr_bool(int e1, int reg) |
2357 { | 2357 { |
2358 int e2,reg0; | 2358 int e2,reg0; |
2359 int op = car(e1); | 2359 int op = car(e1); |
2360 if (!( | 2360 if (!( |
2361 op== GT || op== LT || op== UGT || op== ULT || | 2361 op== GT || op== LT || op== UGT || op== ULT || |
2362 op== ULE || op== UGE || op== LE || op== GE || | 2362 op== ULE || op== UGE || op== LE || op== GE || |
2363 op== EQ || op== NEQ | 2363 op== EQ || op== NEQ |
2364 )) return 0; | 2364 )) return 0; |
2365 if (car(caddr(e1))==CONST && is_stage1_const(cadr(caddr(e1)),CMP)) { | 2365 if (car(caddr(e1))==CONST && is_stage1_const(cadr(caddr(e1)),CMP)) { |
2366 g_expr(cadr(e1)); | 2366 g_expr(cadr(e1)); |
2367 reg0 = creg; | 2367 reg0 = creg; |
2368 use_int(reg); | 2368 use_int(reg); |
2369 pcond(op, cadr(caddr(e1)),reg0,reg,1,0,COND_VALUE_CONST); | 2369 pcond(op, cadr(caddr(e1)),reg0,reg,1,0,COND_VALUE_CONST); |
2370 } else { | 2370 } else { |
2371 g_expr(cadr(e1)); | 2371 g_expr(cadr(e1)); |
2372 emit_push(); | 2372 emit_push(); |
2373 g_expr(caddr(e1)); | 2373 g_expr(caddr(e1)); |
2374 e2 = emit_pop(1); | 2374 e2 = emit_pop(1); |
2375 reg0 = creg; | 2375 reg0 = creg; |
2376 use_int(reg); | 2376 use_int(reg); |
2377 pcond(op, reg0,e2,reg,1,0,COND_VALUE); | 2377 pcond(op, reg0,e2,reg,1,0,COND_VALUE); |
2378 emit_pop_free(e2); | 2378 emit_pop_free(e2); |
2379 } | 2379 } |
2380 return 1; | 2380 return 1; |
2381 } | 2381 } |
2382 | 2382 |
2383 int | 2383 int |
2385 { | 2385 { |
2386 int e2; | 2386 int e2; |
2387 int op = car(e1); | 2387 int op = car(e1); |
2388 | 2388 |
2389 if (car(caddr(e1))==CONST && is_stage1_const(cadr(caddr(e1)),CMP)) { | 2389 if (car(caddr(e1))==CONST && is_stage1_const(cadr(caddr(e1)),CMP)) { |
2390 g_expr(cadr(e1)); | 2390 g_expr(cadr(e1)); |
2391 pcond(op, cadr(caddr(e1)),creg,0,cond,l1,COND_BRANCH_CONST); | 2391 pcond(op, cadr(caddr(e1)),creg,0,cond,l1,COND_BRANCH_CONST); |
2392 } else { | 2392 } else { |
2393 g_expr(cadr(e1)); | 2393 g_expr(cadr(e1)); |
2394 emit_push(); | 2394 emit_push(); |
2395 g_expr(caddr(e1)); | 2395 g_expr(caddr(e1)); |
2396 e2 = emit_pop(1); | 2396 e2 = emit_pop(1); |
2397 pcond(op, creg,e2,0,cond,l1,COND_BRANCH); | 2397 pcond(op, creg,e2,0,cond,l1,COND_BRANCH); |
2398 emit_pop_free(e2); | 2398 emit_pop_free(e2); |
2399 } | 2399 } |
2400 return l1; | 2400 return l1; |
2401 } | 2401 } |
2402 | 2402 |
2403 #define CMP_C1T (-1) | 2403 #define CMP_C1T (-1) |
2411 void | 2411 void |
2412 jmp(int l) | 2412 jmp(int l) |
2413 { | 2413 { |
2414 printf("\tbr\t.LC%d\n",l); | 2414 printf("\tbr\t.LC%d\n",l); |
2415 if (inst_count>CONST_TBL_COUNT/2) { | 2415 if (inst_count>CONST_TBL_COUNT/2) { |
2416 const_list_table(); | 2416 const_list_table(); |
2417 } | 2417 } |
2418 } | 2418 } |
2419 | 2419 |
2420 void | 2420 void |
2421 code_comment(char *s) | 2421 code_comment(char *s) |
2426 static int | 2426 static int |
2427 code_register_restore(int reg_save,int freg_save,int disp) | 2427 code_register_restore(int reg_save,int freg_save,int disp) |
2428 { | 2428 { |
2429 int i; | 2429 int i; |
2430 if (freg_save>0) { | 2430 if (freg_save>0) { |
2431 i=reg_save*SIZE_OF_INT+ | 2431 i=reg_save*SIZE_OF_INT+ |
2432 freg_save*SIZE_OF_DOUBLE + 20; | 2432 freg_save*SIZE_OF_DOUBLE + 20; |
2433 printf("\tlqd\t$sp,%d($sp)\n",i); | 2433 printf("\tlqd\t$sp,%d($sp)\n",i); |
2434 } | 2434 } |
2435 for (i=reg_var_num(0);i<reg_var_num(reg_save);i++) { | 2435 for (i=reg_var_num(0);i<reg_var_num(reg_save);i++) { |
2436 printf("\tlqd\t%s,-%d($sp)\n",register_name(i),-disp); | 2436 printf("\tlqd\t%s,-%d($sp)\n",register_name(i),-disp); |
2437 disp -= SIZE_OF_FLOAT*4; | 2437 disp -= SIZE_OF_FLOAT*4; |
2438 } | 2438 } |
2439 return disp; | 2439 return disp; |
2440 } | 2440 } |
2441 | 2441 |
2442 static int entry_label; | 2442 static int entry_label; |
2443 | 2443 |
2444 void | 2444 void |
2445 code_enter(char *name) | 2445 code_enter(char *name) |
2446 { | 2446 { |
2447 if (output_mode!=TEXT_EMIT_MODE) | 2447 if (output_mode!=TEXT_EMIT_MODE) |
2448 text_mode(3); | 2448 text_mode(3); |
2449 else | 2449 else |
2450 printf("\t.align 3\n"); | 2450 printf("\t.align 3\n"); |
2451 if (stmode!=STATIC) | 2451 if (stmode!=STATIC) |
2452 printf("\t.globl\t%s\n",name); | 2452 printf("\t.globl\t%s\n",name); |
2453 printf("\t.type\t%s,function\n",name); | 2453 printf("\t.type\t%s,function\n",name); |
2454 r1_offset_label = fwdlabel(); | 2454 r1_offset_label = fwdlabel(); |
2455 max_func_args = 0; | 2455 max_func_args = 0; |
2456 printf("%s:\n",name); | 2456 printf("%s:\n",name); |
2457 code_label_value(r1_offset_label,REG_ip); | 2457 code_label_value(r1_offset_label,REG_ip); |
2476 | 2476 |
2477 void | 2477 void |
2478 enter(char *name) | 2478 enter(char *name) |
2479 { | 2479 { |
2480 if (output_mode!=TEXT_EMIT_MODE) | 2480 if (output_mode!=TEXT_EMIT_MODE) |
2481 text_mode(2); | 2481 text_mode(2); |
2482 else | 2482 else |
2483 printf("\t.align 2\n"); | 2483 printf("\t.align 2\n"); |
2484 | 2484 |
2485 max_func_args = 0; | 2485 max_func_args = 0; |
2486 | 2486 |
2487 lvar_offset_label = fwdlabel(); | 2487 lvar_offset_label = fwdlabel(); |
2488 // r1_offset_label = fwdlabel(); | 2488 // r1_offset_label = fwdlabel(); |
2489 printf("\t.type\t%s,function\n",name); | 2489 printf("\t.type\t%s,function\n",name); |
2490 if (stmode!=STATIC) | 2490 if (stmode!=STATIC) |
2491 printf("\t.globl\t%s\n",name); | 2491 printf("\t.globl\t%s\n",name); |
2492 printf("%s:\n",name); | 2492 printf("%s:\n",name); |
2493 //printf("\tmov\t$sp, $lr,0\n"); | 2493 //printf("\tmov\t$sp, $lr,0\n"); |
2494 printf("\tstqd\t$lr,16($sp)\n"); | 2494 printf("\tstqd\t$lr,16($sp)\n"); |
2495 printf("\tstqd\t$sp,-32($sp)\n"); | 2495 printf("\tstqd\t$sp,-32($sp)\n"); |
2496 printf("\tai\t$sp,$sp,-32\n"); | 2496 printf("\tai\t$sp,$sp,-32\n"); |
2497 //gen_jmp(entry_label = fwdlabel()); | 2497 //gen_jmp(entry_label = fwdlabel()); |
2498 //register_save_return_label = backdef(); | 2498 //register_save_return_label = backdef(); |
2499 clear_ptr_cache(); | 2499 clear_ptr_cache(); |
2500 } | 2500 } |
2501 | 2501 |
2513 } | 2513 } |
2514 | 2514 |
2515 void | 2515 void |
2516 code_ret() | 2516 code_ret() |
2517 { | 2517 { |
2518 //printf("\tmov\tpc, lr\n"); | 2518 //printf("\tmov\tpc, lr\n"); |
2519 control=0; | 2519 control=0; |
2520 } | 2520 } |
2521 | 2521 |
2522 static void | 2522 static void |
2523 make_return_continuation() | 2523 make_return_continuation() |
2524 { | 2524 { |
2525 fwddef(retcont); | 2525 fwddef(retcont); |
2526 if (cadr(fnptr->ty)==FLOAT) { | 2526 if (cadr(fnptr->ty)==FLOAT) { |
2527 #if FLOAT_CODE | 2527 #if FLOAT_CODE |
2528 creg = cadr(get_input_dregister_var(0,0,1,0)); | 2528 creg = cadr(get_input_dregister_var(0,0,1,0)); |
2529 set_ireg(RET_REGISTER,1); | 2529 set_ireg(RET_REGISTER,1); |
2530 #endif | 2530 #endif |
2531 printf("\t%s\t%s, %s, 0\n",movef(0), | 2531 printf("\t%s\t%s, %s, 0\n",movef(0), |
2532 register_name(REG_fp),register_name( | 2532 register_name(REG_fp),register_name( |
2533 cadr(get_input_register_var(1,0,1,0))); | 2533 cadr(get_input_register_var(1,0,1,0))); |
2534 } else if (cadr(fnptr->ty)==DOUBLE) { | 2534 } else if (cadr(fnptr->ty)==DOUBLE) { |
2535 #if FLOAT_CODE | 2535 #if FLOAT_CODE |
2536 creg = cadr(get_input_dregister_var(0,0,1,1)); | 2536 creg = cadr(get_input_dregister_var(0,0,1,1)); |
2537 set_ireg(RET_REGISTER,1); | 2537 set_ireg(RET_REGISTER,1); |
2538 printf("\t%s\t%s, %s, 0\n",movef(0), | 2538 printf("\t%s\t%s, %s, 0\n",movef(0), |
2539 register_name(REG_fp),register_name( | 2539 register_name(REG_fp),register_name( |
2540 cadr(get_input_register_var(1,0,1,0))); | 2540 cadr(get_input_register_var(1,0,1,0))); |
2541 #endif | 2541 #endif |
2542 } else if (cadr(fnptr->ty)>0&&( | 2542 } else if (cadr(fnptr->ty)>0&&( |
2543 car(cadr(fnptr->ty))==STRUCT || | 2543 car(cadr(fnptr->ty))==STRUCT || |
2544 car(cadr(fnptr->ty))==UNION)) { | 2544 car(cadr(fnptr->ty))==UNION)) { |
2545 sz = size(cadr(fnptr->ty)); | 2545 sz = size(cadr(fnptr->ty)); |
2546 code_const(sz,REGISTER_OPERAND); | 2546 code_const(sz,REGISTER_OPERAND); |
2547 printf("\tsf\t$1, $2, $sp\n"); | 2547 printf("\tsf\t$1, $2, $sp\n"); |
2548 printf("\tlqd\t$1, %d($sp)\n",(my_func_args-1)*SIZE_OF_INT); | 2548 printf("\tlqd\t$1, %d($sp)\n",(my_func_args-1)*SIZE_OF_INT); |
2549 // emit_copy(6,3,sz,0,1,1); | 2549 // emit_copy(6,3,sz,0,1,1); |
2550 printf("\t%s\t%s, %s, 0\n",movef(0), | 2550 printf("\t%s\t%s, %s, 0\n",movef(0), |
2551 register_name(REG_fp),register_name( | 2551 register_name(REG_fp),register_name( |
2552 cadr(get_input_register_var(1,0,1,0))); | 2552 cadr(get_input_register_var(1,0,1,0))); |
2553 } else if (cadr(fnptr->ty)!=VOID) { | 2553 } else if (cadr(fnptr->ty)!=VOID) { |
2554 creg = cadr(get_input_register_var(0,0,1)); | 2554 creg = cadr(get_input_register_var(0,0,1)); |
2555 if (creg!=RET_REGISTER) | 2555 if (creg!=RET_REGISTER) |
2556 set_ireg(RET_REGISTER,1); | 2556 set_ireg(RET_REGISTER,1); |
2557 printf("\t%s\t%s, %s, 0\n",movef(0), | 2557 printf("\t%s\t%s, %s, 0\n",movef(0), |
2558 register_name(REG_fp),register_name( | 2558 register_name(REG_fp),register_name( |
2559 cadr(get_input_register_var(1,0,1,0))); | 2559 cadr(get_input_register_var(1,0,1,0))); |
2560 } | 2560 } |
2561 code_unfix_frame_pointer(); | 2561 code_unfix_frame_pointer(); |
2562 } | 2562 } |
2563 | 2563 |
2564 void | 2564 void |
2565 leave(int control0, char *name) | 2565 leave(int control0, char *name) |
2566 { | 2566 { |
2567 if (control0) { | 2567 if (control0) { |
2568 code_set_return_register(1); | 2568 code_set_return_register(1); |
2569 } else | 2569 } else |
2570 text_mode(2); | 2570 text_mode(2); |
2571 if (retcont) { | 2571 if (retcont) { |
2572 /* return from CbC segement */ | 2572 /* return from CbC segement */ |
2573 if (control0) gen_jmp(retlabel); | 2573 if (control0) gen_jmp(retlabel); |
2574 make_return_continuation(); | 2574 make_return_continuation(); |
2575 } | 2575 } |
2576 fwddef(retlabel); | 2576 fwddef(retlabel); |
2577 | 2577 |
2578 code_offset_set(fnptr); | 2578 code_offset_set(fnptr); |
2579 code_register_restore(max_reg_var,max_reg_var,0); | 2579 code_register_restore(max_reg_var,max_reg_var,0); |
2582 | 2582 |
2583 // entry part (save register) | 2583 // entry part (save register) |
2584 | 2584 |
2585 fwddef(entry_label); | 2585 fwddef(entry_label); |
2586 if (arg_on_register>0) | 2586 if (arg_on_register>0) |
2587 printf("\tsfi\t$sp, $sp, %d\n",arg_on_register); | 2587 printf("\tsfi\t$sp, $sp, %d\n",arg_on_register); |
2588 // code_register_save(max_reg_var,max_reg_var,0); | 2588 // code_register_save(max_reg_var,max_reg_var,0); |
2589 | 2589 |
2590 code_add(REG_sp,disp-max_func_args*SIZE_OF_INT,REG_sp); | 2590 code_add(REG_sp,disp-max_func_args*SIZE_OF_INT,REG_sp); |
2591 gen_jmp(register_save_return_label); | 2591 gen_jmp(register_save_return_label); |
2592 local_table(); | 2592 local_table(); |
2604 } | 2604 } |
2605 | 2605 |
2606 int | 2606 int |
2607 code_get_fixed_creg(int reg,int type) { | 2607 code_get_fixed_creg(int reg,int type) { |
2608 if (reg==USE_CREG) { | 2608 if (reg==USE_CREG) { |
2609 if (regs[CREG_REGISTER]==0||regs[CREG_REGISTER]==PTRC_REG) { | 2609 if (regs[CREG_REGISTER]==0||regs[CREG_REGISTER]==PTRC_REG) { |
2610 set_ireg(CREG_REGISTER,regs[creg]==USING_REG); | 2610 set_ireg(CREG_REGISTER,regs[creg]==USING_REG); |
2611 return CREG_REGISTER; | 2611 return CREG_REGISTER; |
2612 } | 2612 } |
2613 } | 2613 } |
2614 use_int(reg); | 2614 use_int(reg); |
2615 return reg; | 2615 return reg; |
2616 } | 2616 } |
2617 | 2617 |
2634 case SHORT: case USHORT: d = data_alignment & 1; break; | 2634 case SHORT: case USHORT: d = data_alignment & 1; break; |
2635 default: d = data_alignment & 3; | 2635 default: d = data_alignment & 3; |
2636 } | 2636 } |
2637 if (d) { | 2637 if (d) { |
2638 printf("\t.align 2\n"); | 2638 printf("\t.align 2\n"); |
2639 data_alignment = 0; | 2639 data_alignment = 0; |
2640 } | 2640 } |
2641 } | 2641 } |
2642 | 2642 |
2643 static void | 2643 static void |
2644 ascii(char *s) | 2644 ascii(char *s) |
2645 { | 2645 { |
2646 printf("\t.string \""); | 2646 printf("\t.string \""); |
2647 while(*s) { | 2647 while(*s) { |
2648 if (*s=='\n') | 2648 if (*s=='\n') |
2649 printf("%cn",92); | 2649 printf("%cn",92); |
2650 else if (*s<' ') | 2650 else if (*s<' ') |
2651 printf("%c%03o",92,*s); | 2651 printf("%c%03o",92,*s); |
2652 else if (*s=='\\') | 2652 else if (*s=='\\') |
2653 printf("\\\\"); | 2653 printf("\\\\"); |
2654 else if (*s==34) | 2654 else if (*s==34) |
2655 printf("%c%c",92,34); | 2655 printf("%c%c",92,34); |
2656 else | 2656 else |
2657 printf("%c",*s); | 2657 printf("%c",*s); |
2658 s++; | 2658 s++; |
2659 } | 2659 } |
2660 printf("\\0%c\n",34); | 2660 printf("\\0%c\n",34); |
2661 } | 2661 } |
2662 | 2662 |
2663 int | 2663 int |
2692 int t = type_value(n->ty); | 2692 int t = type_value(n->ty); |
2693 if (e>0 && car(e)==STRING && t>0 && car(t)==ARRAY && | 2693 if (e>0 && car(e)==STRING && t>0 && car(t)==ARRAY && |
2694 (type_value(cadr(t))==CHAR||type_value(cadr(t))==UCHAR)) { | 2694 (type_value(cadr(t))==CHAR||type_value(cadr(t))==UCHAR)) { |
2695 cstring_mode(); | 2695 cstring_mode(); |
2696 } else | 2696 } else |
2697 data_mode(n->nm); | 2697 data_mode(n->nm); |
2698 code_align(a); | 2698 code_align(a); |
2699 if (n && n->sc!=STATIC) | 2699 if (n && n->sc!=STATIC) |
2700 printf("\t.globl\t%s\n",n->nm); | 2700 printf("\t.globl\t%s\n",n->nm); |
2701 printf("%s:\n",n->nm); | 2701 printf("%s:\n",n->nm); |
2702 } | 2702 } |
2703 | 2703 |
2704 void | 2704 void |
2705 emit_space(int sp) | 2705 emit_space(int sp) |
2735 { | 2735 { |
2736 #if LONGLONG_CODE | 2736 #if LONGLONG_CODE |
2737 long long ll = lcadr(e); | 2737 long long ll = lcadr(e); |
2738 data_mode(0); | 2738 data_mode(0); |
2739 #if (ENDIAN_L==0) | 2739 #if (ENDIAN_L==0) |
2740 printf("\t.long\t0x%x,0x%x\n",code_l1(ll),code_l2(ll)); | 2740 printf("\t.long\t0x%x,0x%x\n",code_l1(ll),code_l2(ll)); |
2741 #else | 2741 #else |
2742 printf("\t.long\t0x%x,0x%x\n",code_l2(ll),code_l1(ll)); | 2742 printf("\t.long\t0x%x,0x%x\n",code_l2(ll),code_l1(ll)); |
2743 #endif | 2743 #endif |
2744 #endif | 2744 #endif |
2745 } | 2745 } |
2746 | 2746 |
2747 void | 2747 void |
2749 { | 2749 { |
2750 #if FLOAT_CODE | 2750 #if FLOAT_CODE |
2751 double d = dcadr(e); | 2751 double d = dcadr(e); |
2752 data_mode(0); | 2752 data_mode(0); |
2753 #if (ENDIAN_D==0) | 2753 #if (ENDIAN_D==0) |
2754 printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d)); | 2754 printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d)); |
2755 #else | 2755 #else |
2756 printf("\t.long\t0x%x,0x%x\n",code_d2(d),code_d1(d)); | 2756 printf("\t.long\t0x%x,0x%x\n",code_d2(d),code_d1(d)); |
2757 #endif | 2757 #endif |
2758 #endif | 2758 #endif |
2759 } | 2759 } |
2760 | 2760 |
2761 void | 2761 void |
2771 void | 2771 void |
2772 emit_address(char *s,int offset) | 2772 emit_address(char *s,int offset) |
2773 { | 2773 { |
2774 data_mode(0); | 2774 data_mode(0); |
2775 if (offset) | 2775 if (offset) |
2776 printf("\t.word %s+%d\n",s,offset); | 2776 printf("\t.word %s+%d\n",s,offset); |
2777 else | 2777 else |
2778 printf("\t.word %s\n",s); | 2778 printf("\t.word %s\n",s); |
2779 } | 2779 } |
2780 | 2780 |
2781 void | 2781 void |
2782 emit_label(int labelno) | 2782 emit_label(int labelno) |
2783 { | 2783 { |
2790 { | 2790 { |
2791 #ifdef DOT_SIZE | 2791 #ifdef DOT_SIZE |
2792 int lb; | 2792 int lb; |
2793 #endif | 2793 #endif |
2794 if (mode==GDECL) { | 2794 if (mode==GDECL) { |
2795 data_mode(0); | 2795 data_mode(0); |
2796 #ifdef DOT_SIZE | 2796 #ifdef DOT_SIZE |
2797 lb=fwdlabel(); | 2797 lb=fwdlabel(); |
2798 printf(".LC%d:\n",lb); | 2798 printf(".LC%d:\n",lb); |
2799 printf("\t.size\t%s,.LC%d-%s\n",n->nm,lb,n->nm); | 2799 printf("\t.size\t%s,.LC%d-%s\n",n->nm,lb,n->nm); |
2800 #endif | 2800 #endif |
2801 } | 2801 } |
2802 } | 2802 } |
2803 | 2803 |
2804 | 2804 |
2805 static void | 2805 static void |
2806 comm(NMTBL *n) | 2806 comm(NMTBL *n) |
2807 { | 2807 { |
2808 //printf(".comm %s,%d @ %d\n",n->nm,size(n->ty), | 2808 //printf(".comm %s,%d @ %d\n",n->nm,size(n->ty), |
2809 //(n->ty==DOUBLE||n->ty==LONGLONG||n->ty==ULONGLONG)?8:4 | 2809 //(n->ty==DOUBLE||n->ty==LONGLONG||n->ty==ULONGLONG)?8:4 |
2810 //); | 2810 //); |
2811 } | 2811 } |
2812 | 2812 |
2813 void | 2813 void |
2814 global_table(void) | 2814 global_table(void) |
2815 { | 2815 { |
2816 NMTBL *n; | 2816 NMTBL *n; |
2817 int init; | 2817 int init; |
2818 init=0; | 2818 init=0; |
2819 for(n=global_list;n;n=n->next) { | 2819 for(n=global_list;n;n=n->next) { |
2820 if ((n->sc == GVAR) && n->dsp != -1) { | 2820 if ((n->sc == GVAR) && n->dsp != -1) { |
2821 /* n->dsp = -1 means initialized global */ | 2821 /* n->dsp = -1 means initialized global */ |
2822 if (init==0) { | 2822 if (init==0) { |
2823 data_mode(0); | 2823 data_mode(0); |
2824 init=1; | 2824 init=1; |
2825 } | 2825 } |
2826 comm(n); | 2826 comm(n); |
2827 } else if ((n->sc==STATIC) && n->dsp != -1) { | 2827 } else if ((n->sc==STATIC) && n->dsp != -1) { |
2828 /* n->dsp = -1 means initialized global */ | 2828 /* n->dsp = -1 means initialized global */ |
2829 if (is_code(n)||is_function(n)) continue; | 2829 if (is_code(n)||is_function(n)) continue; |
2830 if (init==0) { | 2830 if (init==0) { |
2831 data_mode(0); | 2831 data_mode(0); |
2832 init=1; | 2832 init=1; |
2833 } | 2833 } |
2834 // printf(".local %s\n",n->nm); | 2834 // printf(".local %s\n",n->nm); |
2835 comm(n); | 2835 comm(n); |
2836 } | 2836 } |
2837 } | 2837 } |
2838 } | 2838 } |
2839 | 2839 |
2840 void | 2840 void |
2841 local_table(void) | 2841 local_table(void) |
2846 const_list_table(); | 2846 const_list_table(); |
2847 | 2847 |
2848 init=0; | 2848 init=0; |
2849 /* static local variables */ | 2849 /* static local variables */ |
2850 for(n=local_static_list;n;n=n->next) { | 2850 for(n=local_static_list;n;n=n->next) { |
2851 if (n->sc == STATIC) { | 2851 if (n->sc == STATIC) { |
2852 if (n->dsp != -1) { /* initialized static */ | 2852 if (n->dsp != -1) { /* initialized static */ |
2853 if (init==0) { | 2853 if (init==0) { |
2854 data_mode(0); | 2854 data_mode(0); |
2855 init=1; | 2855 init=1; |
2856 } | 2856 } |
2857 comm(n); | 2857 comm(n); |
2858 } | 2858 } |
2859 } | 2859 } |
2860 } | 2860 } |
2861 text_mode(2); | 2861 text_mode(2); |
2862 } | 2862 } |
2863 | 2863 |
2864 void | 2864 void |
2865 cstring_mode(int align) | 2865 cstring_mode(int align) |
2866 { | 2866 { |
2867 if (output_mode!=RODATA_EMIT_MODE) { | 2867 if (output_mode!=RODATA_EMIT_MODE) { |
2868 printf(".section\t.rodata\n\t.align 2\n"); | 2868 printf(".section\t.rodata\n\t.align 2\n"); |
2869 output_mode = RODATA_EMIT_MODE; | 2869 output_mode = RODATA_EMIT_MODE; |
2870 } | 2870 } |
2871 } | 2871 } |
2872 | 2872 |
2873 void | 2873 void |
2874 text_mode(int align) | 2874 text_mode(int align) |
2875 { | 2875 { |
2876 if (output_mode!=TEXT_EMIT_MODE) { | 2876 if (output_mode!=TEXT_EMIT_MODE) { |
2877 printf(".text\n"); | 2877 printf(".text\n"); |
2878 if (align) printf("\t.align %d\n",align); | 2878 if (align) printf("\t.align %d\n",align); |
2879 output_mode = TEXT_EMIT_MODE; | 2879 output_mode = TEXT_EMIT_MODE; |
2880 } | 2880 } |
2881 } | 2881 } |
2882 | 2882 |
2883 void | 2883 void |
2884 data_mode(char *name) | 2884 data_mode(char *name) |
2885 { | 2885 { |
2886 if (output_mode!=DATA_EMIT_MODE) { | 2886 if (output_mode!=DATA_EMIT_MODE) { |
2887 printf(".data\n"); | 2887 printf(".data\n"); |
2888 output_mode = DATA_EMIT_MODE; | 2888 output_mode = DATA_EMIT_MODE; |
2889 } | 2889 } |
2890 if (name) | 2890 if (name) |
2891 printf("\t.type\t%s,object\n",name); | 2891 printf("\t.type\t%s,object\n",name); |
2892 } | 2892 } |
2893 | 2893 |
2894 #define lib_args(max) if (max_func_args<max) max_func_args=max | 2894 #define lib_args(max) if (max_func_args<max) max_func_args=max |
2895 | 2895 |
2896 #if LONGLONG_CODE||FLOAT_CODE | 2896 #if LONGLONG_CODE||FLOAT_CODE |
2917 extern_define(lib,0,FUNCTION,1); | 2917 extern_define(lib,0,FUNCTION,1); |
2918 printf("\tbr\t%s\n",lib); | 2918 printf("\tbr\t%s\n",lib); |
2919 lib_args(16); | 2919 lib_args(16); |
2920 set_ireg(RET_REGISTER,0); | 2920 set_ireg(RET_REGISTER,0); |
2921 if (reg!=RET_REGISTER) { | 2921 if (reg!=RET_REGISTER) { |
2922 code_register(RET_REGISTER,reg); | 2922 code_register(RET_REGISTER,reg); |
2923 } | 2923 } |
2924 } | 2924 } |
2925 | 2925 |
2926 #if FLOAT_CODE | 2926 #if FLOAT_CODE |
2927 | 2927 |
2957 | 2957 |
2958 void | 2958 void |
2959 code_dregister(int e2,int freg,int d) | 2959 code_dregister(int e2,int freg,int d) |
2960 { | 2960 { |
2961 use_float(d,freg); | 2961 use_float(d,freg); |
2962 if (freg!=e2) { | 2962 if (freg!=e2) { |
2963 if (is_int_reg(e2)) error(-1); | 2963 if (is_int_reg(e2)) error(-1); |
2964 printf("\t%s\t%s, %s, 0\n",movef(d), | 2964 printf("\t%s\t%s, %s, 0\n",movef(d), |
2965 register_name(freg),register_name(e2)); | 2965 register_name(freg),register_name(e2)); |
2966 } | 2966 } |
2967 } | 2967 } |
2968 | 2968 |
2969 void | 2969 void |
2970 code_dassign_gvar(int e2,int freg,int d) | 2970 code_dassign_gvar(int e2,int freg,int d) |
2971 { | 2971 { |
2972 use_float(d,freg); | 2972 use_float(d,freg); |
2973 code_ldf(fstore(d),register_name(freg),cadr(e2), | 2973 code_ldf(fstore(d),register_name(freg),cadr(e2), |
2974 get_ptr_cache(ncaddr(e2)),""); | 2974 get_ptr_cache(ncaddr(e2)),""); |
2975 } | 2975 } |
2976 | 2976 |
2977 void | 2977 void |
2978 code_dassign_lvar(int e2,int freg,int d) | 2978 code_dassign_lvar(int e2,int freg,int d) |
2979 { | 2979 { |
2980 use_float(d,freg); | 2980 use_float(d,freg); |
2981 lvar_intro(e2); | 2981 lvar_intro(e2); |
2982 printf("\t%s\t%s, ",fstore(d),register_name(freg)); | 2982 printf("\t%s\t%s, ",fstore(d),register_name(freg)); |
2983 lvar(e2,""); | 2983 lvar(e2,""); |
2984 } | 2984 } |
2985 | 2985 |
2986 void | 2986 void |
2987 code_dassign(int e2,int freg,int d) | 2987 code_dassign(int e2,int freg,int d) |
2988 { | 2988 { |
2989 use_float(d,freg); | 2989 use_float(d,freg); |
2990 //printf("\t%s\t%s, [%s, #0] @ float\n",fstore(d), | 2990 //printf("\t%s\t%s, [%s, #0] @ float\n",fstore(d), |
2991 printf("\t%s\t%s, 0(%s)\n",fstore(d), | 2991 printf("\t%s\t%s, 0(%s)\n",fstore(d), |
2992 register_name(freg),register_name(e2)); | 2992 register_name(freg),register_name(e2)); |
2993 } | 2993 } |
2994 | 2994 |
2995 void | 2995 void |
2996 code_dassign_dregister(int e2,int d,int freg) { | 2996 code_dassign_dregister(int e2,int d,int freg) { |
2997 use_float(d,freg); | 2997 use_float(d,freg); |
2998 if (e2!=freg) { | 2998 if (e2!=freg) { |
2999 printf("\t%s\t%s, %s, 0\n",movef(d), | 2999 printf("\t%s\t%s, %s, 0\n",movef(d), |
3000 register_name(e2),register_name(freg)); | 3000 register_name(e2),register_name(freg)); |
3001 } | 3001 } |
3002 } | 3002 } |
3003 | 3003 |
3004 static double d0 = 1.0; | 3004 static double d0 = 1.0; |
3005 | 3005 |
3033 | 3033 |
3034 char *frn; | 3034 char *frn; |
3035 int label,disp; | 3035 int label,disp; |
3036 | 3036 |
3037 use_float(d,freg); | 3037 use_float(d,freg); |
3038 frn = register_name(freg); | 3038 frn = register_name(freg); |
3039 if (value==0 || value==1 || value==10) { | 3039 if (value==0 || value==1 || value==10) { |
3040 printf("\t%s\t%s, %s, %d\n",movef(d),frn,frn,(int)value); | 3040 printf("\t%s\t%s, %s, %d\n",movef(d),frn,frn,(int)value); |
3041 } else if (value==-1 || value==-10) { | 3041 } else if (value==-1 || value==-10) { |
3042 printf("\t%s\t%s, %d\n",d?"mnfd":"mnfs",frn,(int)-value); | 3042 printf("\t%s\t%s, %d\n",d?"mnfd":"mnfs",frn,(int)-value); |
3043 } else if (d) { | 3043 } else if (d) { |
3044 #if ENDIAN_D==0 | 3044 #if ENDIAN_D==0 |
3045 disp = search_double_const(DCONST, | 3045 disp = search_double_const(DCONST, |
3046 code_d1(value),code_d2(value),&label); | 3046 code_d1(value),code_d2(value),&label); |
3047 #else | 3047 #else |
3048 disp = search_double_const(DCONST, | 3048 disp = search_double_const(DCONST, |
3049 code_d2(value),code_d1(value),&label); | 3049 code_d2(value),code_d1(value),&label); |
3050 #endif | 3050 #endif |
3051 printf("\tlqd\t%s, .LC%d+%d($sp)\n",frn,label,disp); | 3051 printf("\tlqd\t%s, .LC%d+%d($sp)\n",frn,label,disp); |
3052 } else { | 3052 } else { |
3053 } | 3053 } |
3054 } | 3054 } |
3055 | 3055 |
3056 | 3056 |
3057 void | 3057 void |
3058 code_builtin_fabsf(int e) | 3058 code_builtin_fabsf(int e) |
3074 void | 3074 void |
3075 code_dneg(int freg,int d) | 3075 code_dneg(int freg,int d) |
3076 { | 3076 { |
3077 char *frn; | 3077 char *frn; |
3078 use_float(d,freg); | 3078 use_float(d,freg); |
3079 frn = register_name(freg); | 3079 frn = register_name(freg); |
3080 printf("\t%s\t%s, %s\n",d?"mnfd":"mnfs",frn,frn); | 3080 printf("\t%s\t%s, %s\n",d?"mnfd":"mnfs",frn,frn); |
3081 } | 3081 } |
3082 | 3082 |
3083 void | 3083 void |
3084 code_d2i0(int reg,int d) | 3084 code_d2i0(int reg,int d) |
3085 { | 3085 { |
3086 int lreg; | 3086 int lreg; |
3087 use_float(d,reg); | 3087 use_float(d,reg); |
3088 lreg = get_register(); | 3088 lreg = get_register(); |
3089 //printf("\tfixz\t%s, %s\n",register_name(lreg),register_name(reg)); | 3089 //printf("\tfixz\t%s, %s\n",register_name(lreg),register_name(reg)); |
3090 set_ireg(lreg,0); | 3090 set_ireg(lreg,0); |
3091 return; | 3091 return; |
3092 } | 3092 } |
3093 | 3093 |
3094 void | 3094 void |
3095 code_i2d0(int reg,int d) | 3095 code_i2d0(int reg,int d) |
3096 { | 3096 { |
3097 int lreg; | 3097 int lreg; |
3098 use_int(reg); | 3098 use_int(reg); |
3099 lreg = get_dregister(1); | 3099 lreg = get_dregister(1); |
3100 printf("\tflt\t%s, %s\n", | 3100 printf("\tflt\t%s, %s\n", |
3101 register_name(lreg),register_name(reg)); | 3101 register_name(lreg),register_name(reg)); |
3102 set_ireg(lreg,0); | 3102 set_ireg(lreg,0); |
3103 return; | 3103 return; |
3104 } | 3104 } |
3105 | 3105 |
3106 void | 3106 void |
3107 code_d2u0(int reg,int d) | 3107 code_d2u0(int reg,int d) |
3108 { | 3108 { |
3109 int lreg,reg0; | 3109 int lreg,reg0; |
3110 char *lrn,*frn,*crn; | 3110 char *lrn,*frn,*crn; |
3111 // u = (d>2.1e9)?((int)(d-2.1e9)^2147483648):(int)d | 3111 // u = (d>2.1e9)?((int)(d-2.1e9)^2147483648):(int)d |
3112 use_float(1,reg); | 3112 use_float(1,reg); |
3113 frn = register_name(reg); | 3113 frn = register_name(reg); |
3114 if (!d) printf("\tori\t%s, %s, 0\n",frn,frn); | 3114 if (!d) printf("\tori\t%s, %s, 0\n",frn,frn); |
3115 emit_dpush(1); | 3115 emit_dpush(1); |
3116 code_dconst(dlist2(DCONST,2.147483648e9),USE_CREG,1); | 3116 code_dconst(dlist2(DCONST,2.147483648e9),USE_CREG,1); |
3117 lrn = register_name(lreg = emit_dpop(d)); | 3117 lrn = register_name(lreg = emit_dpop(d)); |
3118 frn = register_name(creg); | 3118 frn = register_name(creg); |
3119 set_ireg(reg0=get_register(),0); | 3119 set_ireg(reg0=get_register(),0); |
3120 crn = register_name(reg0); | 3120 crn = register_name(reg0); |
3121 printf("\tcmfe\t%s, %s\n",lrn,frn); | 3121 printf("\tcmfe\t%s, %s\n",lrn,frn); |
3122 printf("\tbr\t1f\n"); | 3122 printf("\tbr\t1f\n"); |
3123 //printf("\tfixz\t%s, %s\n",crn,lrn); | 3123 //printf("\tfixz\t%s, %s\n",crn,lrn); |
3124 printf("\tb\t2f\n"); | 3124 printf("\tb\t2f\n"); |
3125 printf("1:\n"); | 3125 printf("1:\n"); |
3126 printf("\tsufd\t%s, %s, %s\n",lrn,lrn,frn); | 3126 printf("\tsufd\t%s, %s, %s\n",lrn,lrn,frn); |
3127 //printf("\tfixz\t%s, %s\n",crn,lrn); | 3127 //printf("\tfixz\t%s, %s\n",crn,lrn); |
3128 printf("\teor\t%s, %s, #-2147483648\n",crn,crn); | 3128 printf("\teor\t%s, %s, #-2147483648\n",crn,crn); |
3129 printf("2:\n"); | 3129 printf("2:\n"); |
3130 emit_dpop_free(lreg,d); | 3130 emit_dpop_free(lreg,d); |
3131 return; | 3131 return; |
3132 } | 3132 } |
3133 | 3133 |
3134 void | 3134 void |
3135 code_u2d0(int reg,int d) | 3135 code_u2d0(int reg,int d) |
3136 { | 3136 { |
3137 int freg1; | 3137 int freg1; |
3138 char *crn,*frn,*lrn; | 3138 char *crn,*frn,*lrn; |
3139 use_int(reg); | 3139 use_int(reg); |
3140 crn = register_name(reg); | 3140 crn = register_name(reg); |
3141 set_ireg(reg=get_dregister(1),0); | 3141 set_ireg(reg=get_dregister(1),0); |
3142 frn = register_name(reg); | 3142 frn = register_name(reg); |
3143 printf("\tfltd\t%s, %s\n",frn,crn); | 3143 printf("\tfltd\t%s, %s\n",frn,crn); |
3144 printf("\tceqi\t%s, %s, 0\n",crn,crn); | 3144 printf("\tceqi\t%s, %s, 0\n",crn,crn); |
3145 printf("\tbr\t1f\n"); | 3145 printf("\tbr\t1f\n"); |
3146 freg1 = get_dregister(1); | 3146 freg1 = get_dregister(1); |
3147 code_dconst(dlist2(DCONST,4.29496729600000000000e9),freg1,1); | 3147 code_dconst(dlist2(DCONST,4.29496729600000000000e9),freg1,1); |
3148 frn = register_name(creg); | 3148 frn = register_name(creg); |
3149 lrn = register_name(freg1); | 3149 lrn = register_name(freg1); |
3150 printf("\tadfd\t%s, %s, %s\n",frn,frn,lrn); | 3150 printf("\tadfd\t%s, %s, %s\n",frn,frn,lrn); |
3151 printf("1:\n"); | 3151 printf("1:\n"); |
3152 if (!d) | 3152 if (!d) |
3153 printf("\tmvfs\t%s, %s\n",frn,frn); | 3153 printf("\tmvfs\t%s, %s\n",frn,frn); |
3154 free_register(freg1); | 3154 free_register(freg1); |
3155 return; | 3155 return; |
3156 } | 3156 } |
3157 | 3157 |
3158 void | 3158 void |
3159 code_d2f(int reg) { | 3159 code_d2f(int reg) { |
3160 char *frn; | 3160 char *frn; |
3161 frn = register_name(creg); | 3161 frn = register_name(creg); |
3162 printf("\tmvfs\t%s,%s\n",frn,frn); | 3162 printf("\tmvfs\t%s,%s\n",frn,frn); |
3163 return; | 3163 return; |
3164 } | 3164 } |
3165 | 3165 |
3166 void | 3166 void |
3167 code_f2d(int reg) { | 3167 code_f2d(int reg) { |
3168 char *frn; | 3168 char *frn; |
3169 frn = register_name(creg); | 3169 frn = register_name(creg); |
3170 printf("\tori\t%s, %s, 0\n",frn,frn); | 3170 printf("\tori\t%s, %s, 0\n",frn,frn); |
3171 return; | 3171 return; |
3172 } | 3172 } |
3173 | 3173 |
3174 void | 3174 void |
3175 code_d2i(int reg) { | 3175 code_d2i(int reg) { |
3212 } | 3212 } |
3213 | 3213 |
3214 void | 3214 void |
3215 code_drgvar(int e2,int d,int freg) | 3215 code_drgvar(int e2,int d,int freg) |
3216 { | 3216 { |
3217 use_float(d,freg); | 3217 use_float(d,freg); |
3218 code_ldf(fload(d),register_name(freg),cadr(e2), | 3218 code_ldf(fload(d),register_name(freg),cadr(e2), |
3219 get_ptr_cache(ncaddr(e2)),""); | 3219 get_ptr_cache(ncaddr(e2)),""); |
3220 } | 3220 } |
3221 | 3221 |
3222 | 3222 |
3223 void | 3223 void |
3224 code_drlvar(int e2,int d,int freg) | 3224 code_drlvar(int e2,int d,int freg) |
3225 { | 3225 { |
3226 use_float(d,freg); | 3226 use_float(d,freg); |
3227 lvar_intro(e2); | 3227 lvar_intro(e2); |
3228 printf("\t%s\t%s, ",fload(d),register_name(freg)); | 3228 printf("\t%s\t%s, ",fload(d),register_name(freg)); |
3229 lvar(e2,d?"@ double":"@ float"); | 3229 lvar(e2,d?"@ double":"@ float"); |
3230 } | 3230 } |
3231 | 3231 |
3232 void | 3232 void |
3233 code_cmp_drgvar(int e2,int reg,int d,int label,int cond) | 3233 code_cmp_drgvar(int e2,int reg,int d,int label,int cond) |
3234 { | 3234 { |
3271 case FDIV: opn="fdvs"; break; | 3271 case FDIV: opn="fdvs"; break; |
3272 case FMUL: opn="fmls"; break; | 3272 case FMUL: opn="fmls"; break; |
3273 case FCMPGE: | 3273 case FCMPGE: |
3274 case FCMP: opn="cmfe"; cmp=1; break; | 3274 case FCMP: opn="cmfe"; cmp=1; break; |
3275 default: | 3275 default: |
3276 error(-1); return; | 3276 error(-1); return; |
3277 } | 3277 } |
3278 grn = register_name(e1); | 3278 grn = register_name(e1); |
3279 frn = register_name(reg); | 3279 frn = register_name(reg); |
3280 if (cmp) { | 3280 if (cmp) { |
3281 printf("\t%s\t%s, %s\n",opn,grn,frn); | 3281 printf("\t%s\t%s, %s\n",opn,grn,frn); |
3308 | 3308 |
3309 void | 3309 void |
3310 code_register_dassop(int reg,int op,int d) { | 3310 code_register_dassop(int reg,int op,int d) { |
3311 // reg op= dpop() | 3311 // reg op= dpop() |
3312 int xreg; | 3312 int xreg; |
3313 xreg=emit_dpop(d); | 3313 xreg=emit_dpop(d); |
3314 dtosop(op,reg,xreg); | 3314 dtosop(op,reg,xreg); |
3315 emit_dpop_free(xreg,d); | 3315 emit_dpop_free(xreg,d); |
3316 } | 3316 } |
3317 | 3317 |
3318 static int | 3318 static int |
3319 code_dload_1(int d) | 3319 code_dload_1(int d) |
3320 { | 3320 { |
3331 int g,reg0; | 3331 int g,reg0; |
3332 char *grn; | 3332 char *grn; |
3333 int dir=caddr(e1); | 3333 int dir=caddr(e1); |
3334 | 3334 |
3335 if (car(e2)==DREGISTER||car(e2)==FREGISTER) { | 3335 if (car(e2)==DREGISTER||car(e2)==FREGISTER) { |
3336 crn=register_name(cadr(e2)); | 3336 crn=register_name(cadr(e2)); |
3337 grn=register_name(g=code_dload_1(d)); | 3337 grn=register_name(g=code_dload_1(d)); |
3338 if (reg==USE_CREG) { | 3338 if (reg==USE_CREG) { |
3339 reg=get_dregister(d); if (!reg) error(-1); | 3339 reg=get_dregister(d); if (!reg) error(-1); |
3340 set_ireg(reg,0); | 3340 set_ireg(reg,0); |
3341 } | 3341 } |
3342 frn=register_name(reg); | 3342 frn=register_name(reg); |
3343 printf("\t%s\t%s, %s, %s\n", | 3343 printf("\t%s\t%s, %s, %s\n", |
3344 dir>0?"adf":"suf", | 3344 dir>0?"adf":"suf", |
3345 crn,crn,grn); | 3345 crn,crn,grn); |
3346 if (use && reg!=cadr(e2)) { | 3346 if (use && reg!=cadr(e2)) { |
3347 printf("\tmvf\t%s, %s\n",frn,crn); | 3347 printf("\tmvf\t%s, %s\n",frn,crn); |
3348 } | 3348 } |
3349 } else { | 3349 } else { |
3350 g_expr(e2); | 3350 g_expr(e2); |
3351 if (!is_int_reg(creg)) error(-1); | 3351 if (!is_int_reg(creg)) error(-1); |
3352 reg0 = creg; | 3352 reg0 = creg; |
3353 if (reg==USE_CREG) { | 3353 if (reg==USE_CREG) { |
3354 reg=get_dregister(d); if (!reg) error(-1); | 3354 reg=get_dregister(d); if (!reg) error(-1); |
3355 set_ireg(reg,0); | 3355 set_ireg(reg,0); |
3356 } | 3356 } |
3357 grn = register_name(g = code_dload_1(d)); | 3357 grn = register_name(g = code_dload_1(d)); |
3358 frn=register_name(reg); | 3358 frn=register_name(reg); |
3359 code_ldf(fload(d),frn,0,reg0,""); | 3359 code_ldf(fload(d),frn,0,reg0,""); |
3360 printf("\t%s\t%s, %s, %s\n", | 3360 printf("\t%s\t%s, %s, %s\n", |
3361 dir>0?"adf":"suf", | 3361 dir>0?"adf":"suf", |
3362 frn,frn,grn); | 3362 frn,frn,grn); |
3363 code_ldf(fstore(d),frn,0,reg0,""); | 3363 code_ldf(fstore(d),frn,0,reg0,""); |
3364 } | 3364 } |
3365 free_register(g); | 3365 free_register(g); |
3366 } | 3366 } |
3367 | 3367 |
3368 void | 3368 void |
3372 int g,reg0; | 3372 int g,reg0; |
3373 char *grn; | 3373 char *grn; |
3374 int dir=caddr(e1); | 3374 int dir=caddr(e1); |
3375 | 3375 |
3376 if (car(e2)==DREGISTER||car(e2)==FREGISTER) { | 3376 if (car(e2)==DREGISTER||car(e2)==FREGISTER) { |
3377 crn=register_name(cadr(e2)); | 3377 crn=register_name(cadr(e2)); |
3378 grn=register_name(g=code_dload_1(d)); | 3378 grn=register_name(g=code_dload_1(d)); |
3379 if (reg==USE_CREG) { | 3379 if (reg==USE_CREG) { |
3380 reg=get_dregister(d); if (!reg) error(-1); | 3380 reg=get_dregister(d); if (!reg) error(-1); |
3381 set_ireg(reg,0); | 3381 set_ireg(reg,0); |
3382 } | 3382 } |
3383 frn=register_name(reg); | 3383 frn=register_name(reg); |
3384 if (use && reg!=cadr(e2)) { | 3384 if (use && reg!=cadr(e2)) { |
3385 printf("\tmvf\t%s, %s\n",frn,crn); | 3385 printf("\tmvf\t%s, %s\n",frn,crn); |
3386 } | 3386 } |
3387 printf("\t%s\t%s,%s,%s\n",dir>0?"adf":"suf", | 3387 printf("\t%s\t%s,%s,%s\n",dir>0?"adf":"suf", |
3388 crn,crn,grn); | 3388 crn,crn,grn); |
3389 } else { | 3389 } else { |
3390 g_expr(e2); | 3390 g_expr(e2); |
3391 if (!is_int_reg(creg)) error(-1); | 3391 if (!is_int_reg(creg)) error(-1); |
3392 crn=register_name(reg0=creg); | 3392 crn=register_name(reg0=creg); |
3393 if (reg==USE_CREG) { | 3393 if (reg==USE_CREG) { |
3394 reg=get_dregister(d); if (!reg) error(-1); | 3394 reg=get_dregister(d); if (!reg) error(-1); |
3395 set_ireg(reg,0); | 3395 set_ireg(reg,0); |
3396 } | 3396 } |
3397 frn=register_name(reg); | 3397 frn=register_name(reg); |
3398 grn = register_name(g = code_dload_1(d)); | 3398 grn = register_name(g = code_dload_1(d)); |
3399 code_ldf(fload(d),frn,0,reg0,""); | 3399 code_ldf(fload(d),frn,0,reg0,""); |
3400 printf("\t%s\t%s, %s, %s\n", | 3400 printf("\t%s\t%s, %s, %s\n", |
3401 dir>0?"adf":"suf", | 3401 dir>0?"adf":"suf", |
3402 grn,frn,grn); | 3402 grn,frn,grn); |
3403 code_ldf(fstore(d),grn,0,reg0,""); | 3403 code_ldf(fstore(d),grn,0,reg0,""); |
3404 } | 3404 } |
3405 free_register(g); | 3405 free_register(g); |
3406 } | 3406 } |
3407 | 3407 |
3408 | 3408 |
3410 drexpr(int e1, int e2,int l1, int op,int cond) | 3410 drexpr(int e1, int e2,int l1, int op,int cond) |
3411 { | 3411 { |
3412 int op1=0; | 3412 int op1=0; |
3413 char *opn=0; | 3413 char *opn=0; |
3414 if (!cond) { | 3414 if (!cond) { |
3415 switch(op) { | 3415 switch(op) { |
3416 case FOP+GT: | 3416 case FOP+GT: |
3417 return drexpr(e2,e1,l1,FOP+GE,1); | 3417 return drexpr(e2,e1,l1,FOP+GE,1); |
3418 case FOP+GE: | 3418 case FOP+GE: |
3419 return drexpr(e2,e1,l1,FOP+GT,1); | 3419 return drexpr(e2,e1,l1,FOP+GT,1); |
3420 case FOP+EQ: | 3420 case FOP+EQ: |
3421 op=FOP+NEQ; break; | 3421 op=FOP+NEQ; break; |
3422 case FOP+NEQ: | 3422 case FOP+NEQ: |
3423 op=FOP+EQ; break; | 3423 op=FOP+EQ; break; |
3424 case DOP+GT: | 3424 case DOP+GT: |
3425 return drexpr(e2,e1,l1,DOP+GE,1); | 3425 return drexpr(e2,e1,l1,DOP+GE,1); |
3426 case DOP+GE: | 3426 case DOP+GE: |
3427 return drexpr(e2,e1,l1,DOP+GT,1); | 3427 return drexpr(e2,e1,l1,DOP+GT,1); |
3428 case DOP+EQ: | 3428 case DOP+EQ: |
3429 op=DOP+NEQ; break; | 3429 op=DOP+NEQ; break; |
3430 case DOP+NEQ: | 3430 case DOP+NEQ: |
3431 op=DOP+EQ; break; | 3431 op=DOP+EQ; break; |
3432 } | 3432 } |
3433 } | 3433 } |
3434 switch(op) { | 3434 switch(op) { |
3435 case FOP+GT: op1=FOP+CMP; opn = "br"; break; | 3435 case FOP+GT: op1=FOP+CMP; opn = "br"; break; |
3436 case FOP+GE: op1=FOP+CMPGE; opn = "br"; break; | 3436 case FOP+GE: op1=FOP+CMPGE; opn = "br"; break; |
3437 case FOP+EQ: op1=FOP+CMP; opn = "br"; break; | 3437 case FOP+EQ: op1=FOP+CMP; opn = "br"; break; |
3450 int emit_dpop(int d) | 3450 int emit_dpop(int d) |
3451 { | 3451 { |
3452 int xreg,reg; | 3452 int xreg,reg; |
3453 xreg=pop_fregister(); | 3453 xreg=pop_fregister(); |
3454 if (xreg<= -REG_LVAR_OFFSET) { | 3454 if (xreg<= -REG_LVAR_OFFSET) { |
3455 reg = get_dregister(d); | 3455 reg = get_dregister(d); |
3456 code_drlvar(REG_LVAR_OFFSET+xreg,1,reg); | 3456 code_drlvar(REG_LVAR_OFFSET+xreg,1,reg); |
3457 free_lvar(REG_LVAR_OFFSET+xreg); | 3457 free_lvar(REG_LVAR_OFFSET+xreg); |
3458 xreg=reg; | 3458 xreg=reg; |
3459 } | 3459 } |
3460 return xreg; | 3460 return xreg; |
3461 } | 3461 } |
3462 | 3462 |
3463 | 3463 |
3499 l2 = fwdlabel(); | 3499 l2 = fwdlabel(); |
3500 regh = reg; regl = reg; | 3500 regh = reg; regl = reg; |
3501 e3h = e3; e3l = e3; | 3501 e3h = e3; e3l = e3; |
3502 switch(op) { | 3502 switch(op) { |
3503 case LOP+GT: case LOP+GE: | 3503 case LOP+GT: case LOP+GE: |
3504 pcond(GT, regh,e3h,0,1,cond?l1:l2,COND_BRANCH); | 3504 pcond(GT, regh,e3h,0,1,cond?l1:l2,COND_BRANCH); |
3505 pcond(NEQ, regh,e3h,0,1,cond?l2:l1,COND_BRANCH); | 3505 pcond(NEQ, regh,e3h,0,1,cond?l2:l1,COND_BRANCH); |
3506 break; | 3506 break; |
3507 case LOP+UGT: case LOP+UGE: | 3507 case LOP+UGT: case LOP+UGE: |
3508 pcond(UGT, regh,e3h,0,1,cond?l1:l2,COND_BRANCH); | 3508 pcond(UGT, regh,e3h,0,1,cond?l1:l2,COND_BRANCH); |
3509 pcond(NEQ, regh,e3h,0,1,cond?l2:l1,COND_BRANCH); | 3509 pcond(NEQ, regh,e3h,0,1,cond?l2:l1,COND_BRANCH); |
3510 break; | 3510 break; |
3511 case LOP+EQ: | 3511 case LOP+EQ: |
3512 pcond(EQ, regh,e3h,0,0,cond?l2:l1,COND_BRANCH); | 3512 pcond(EQ, regh,e3h,0,0,cond?l2:l1,COND_BRANCH); |
3513 break; | 3513 break; |
3514 case LOP+NEQ: | 3514 case LOP+NEQ: |
3515 pcond(EQ, regh,e3h,0,0,cond?l1:l2,COND_BRANCH); | 3515 pcond(EQ, regh,e3h,0,0,cond?l1:l2,COND_BRANCH); |
3516 break; | 3516 break; |
3517 default: | 3517 default: |
3518 error(-1); | 3518 error(-1); |
3519 } | 3519 } |
3520 pcond(op%LOP,regl,e3l,0,cond,l1,COND_BRANCH); | 3520 pcond(op%LOP,regl,e3l,0,cond,l1,COND_BRANCH); |
3570 void | 3570 void |
3571 code_lregister(int e2,int reg) | 3571 code_lregister(int e2,int reg) |
3572 { | 3572 { |
3573 use_longlong(reg); | 3573 use_longlong(reg); |
3574 if (reg!=e2) { | 3574 if (reg!=e2) { |
3575 lmove(reg,e2); | 3575 lmove(reg,e2); |
3576 } | 3576 } |
3577 } | 3577 } |
3578 | 3578 |
3579 | 3579 |
3580 void | 3580 void |
3621 void | 3621 void |
3622 code_lassign_lregister(int e2,int reg) | 3622 code_lassign_lregister(int e2,int reg) |
3623 { | 3623 { |
3624 use_longlong(reg); | 3624 use_longlong(reg); |
3625 if (e2!=reg) { | 3625 if (e2!=reg) { |
3626 lmove(e2,reg); | 3626 lmove(e2,reg); |
3627 } | 3627 } |
3628 } | 3628 } |
3629 | 3629 |
3630 void | 3630 void |
3631 emit_lpop_free(int xreg) | 3631 emit_lpop_free(int xreg) |
3736 | 3736 |
3737 // reg = reg op oreg | 3737 // reg = reg op oreg |
3738 | 3738 |
3739 use_longlong(reg); | 3739 use_longlong(reg); |
3740 if(oreg==-1) { | 3740 if(oreg==-1) { |
3741 error(-1); | 3741 error(-1); |
3742 } else if (oreg<= -REG_LVAR_OFFSET) { | 3742 } else if (oreg<= -REG_LVAR_OFFSET) { |
3743 ox = get_lregister(); if (ox<0) error(-1); | 3743 ox = get_lregister(); if (ox<0) error(-1); |
3744 use_reg(ox); | 3744 use_reg(ox); |
3745 code_rlvar(oreg+REG_LVAR_OFFSET,ox); | 3745 code_rlvar(oreg+REG_LVAR_OFFSET,ox); |
3746 oreg = ox; | 3746 oreg = ox; |
3747 } | 3747 } |
3748 | 3748 |
3749 switch(op) { | 3749 switch(op) { |
3750 case LLSHIFT: | 3750 case LLSHIFT: |
3751 case LULSHIFT: | 3751 case LULSHIFT: |
3752 code_longlong_lib("__ashldi3",reg,oreg); | 3752 code_longlong_lib("__ashldi3",reg,oreg); |
3753 check_lreg(reg); | 3753 check_lreg(reg); |
3754 if(ox!=-1) free_register(ox); | 3754 if(ox!=-1) free_register(ox); |
3755 return; | 3755 return; |
3756 case LRSHIFT: | 3756 case LRSHIFT: |
3757 code_longlong_lib("__ashrdi3",reg,oreg); | 3757 code_longlong_lib("__ashrdi3",reg,oreg); |
3758 check_lreg(reg); | 3758 check_lreg(reg); |
3759 if(ox!=-1) free_register(ox); | 3759 if(ox!=-1) free_register(ox); |
3760 return; | 3760 return; |
3761 case LURSHIFT: | 3761 case LURSHIFT: |
3762 code_longlong_lib("__lshrdi3",reg,oreg); | 3762 code_longlong_lib("__lshrdi3",reg,oreg); |
3763 check_lreg(reg); | 3763 check_lreg(reg); |
3764 if(ox!=-1) free_register(ox); | 3764 if(ox!=-1) free_register(ox); |
3765 return; | 3765 return; |
3766 } | 3766 } |
3767 orn = register_name(oreg); | 3767 orn = register_name(oreg); |
3768 | 3768 |
3769 crn = register_name(reg); | 3769 crn = register_name(reg); |
3770 | 3770 |
3771 switch(op) { | 3771 switch(op) { |
3772 case LADD: | 3772 case LADD: |
3773 printf("\tadds\t%s, %s, %s\n",crn,crn,orn); | 3773 printf("\tadds\t%s, %s, %s\n",crn,crn,orn); |
3774 | 3774 |
3775 break; | 3775 break; |
3776 case LSUB: | 3776 case LSUB: |
3777 printf("\tsubs\t%s, %s, %s\n",crn,crn,orn); | 3777 printf("\tsubs\t%s, %s, %s\n",crn,crn,orn); |
3778 | 3778 |
3779 break; | 3779 break; |
3780 case LCMP: | 3780 case LCMP: |
3781 error(-1); | 3781 error(-1); |
3782 break; | 3782 break; |
3783 case LBAND: | 3783 case LBAND: |
3784 printf("\tand\t%s, %s, %s\n",crn,crn,orn); | 3784 printf("\tand\t%s, %s, %s\n",crn,crn,orn); |
3785 | 3785 |
3786 break; | 3786 break; |
3787 case LEOR: | 3787 case LEOR: |
3788 printf("\teor\t%s, %s, %s\n",crn,crn,orn); | 3788 printf("\teor\t%s, %s, %s\n",crn,crn,orn); |
3789 | 3789 |
3790 break; | 3790 break; |
3791 case LBOR: | 3791 case LBOR: |
3792 printf("\tor\t%s, %s, %s\n",crn,crn,orn); | 3792 printf("\tor\t%s, %s, %s\n",crn,crn,orn); |
3793 | 3793 |
3794 break; | 3794 break; |
3795 case LMUL: | 3795 case LMUL: |
3796 case LUMUL: | 3796 case LUMUL: |
3797 code_longlong_lib("__muldi3",reg,oreg); | 3797 code_longlong_lib("__muldi3",reg,oreg); |
3798 check_lreg(reg); | 3798 check_lreg(reg); |
3799 break; | 3799 break; |
3800 case LDIV: | 3800 case LDIV: |
3801 code_longlong_lib("__divdi3",reg,oreg); | 3801 code_longlong_lib("__divdi3",reg,oreg); |
3802 check_lreg(reg); | 3802 check_lreg(reg); |
3803 break; | 3803 break; |
3804 case LUDIV: | 3804 case LUDIV: |
3805 code_longlong_lib("__udivdi3",reg,oreg); | 3805 code_longlong_lib("__udivdi3",reg,oreg); |
3806 check_lreg(reg); | 3806 check_lreg(reg); |
3807 break; | 3807 break; |
3808 case LMOD: | 3808 case LMOD: |
3809 code_longlong_lib("__moddi3",reg,oreg); | 3809 code_longlong_lib("__moddi3",reg,oreg); |
3810 check_lreg(reg); | 3810 check_lreg(reg); |
3811 break; | 3811 break; |
3812 case LUMOD: | 3812 case LUMOD: |
3813 code_longlong_lib("__umoddi3",reg,oreg); | 3813 code_longlong_lib("__umoddi3",reg,oreg); |
3814 check_lreg(reg); | 3814 check_lreg(reg); |
3815 break; | 3815 break; |
3816 default: | 3816 default: |
3817 error(-1); | 3817 error(-1); |
3818 } | 3818 } |
3819 if(ox!=-1) free_register(ox); | 3819 if(ox!=-1) free_register(ox); |
3820 if(dx!=-1) free_register(dx); | 3820 if(dx!=-1) free_register(dx); |
3821 } | 3821 } |
3822 | 3822 |
3823 int | 3823 int |
3824 code_lconst_op_p(int op,int e) | 3824 code_lconst_op_p(int op,int e) |
3825 { | 3825 { |
3826 long long v; | 3826 long long v; |
3827 if (car(e)==LCONST) { | 3827 if (car(e)==LCONST) { |
3828 v = lcadr(e); | 3828 v = lcadr(e); |
3829 } else if (car(e)==CONST) { | 3829 } else if (car(e)==CONST) { |
3830 v = cadr(e); | 3830 v = cadr(e); |
3831 } else return 0; | 3831 } else return 0; |
3832 | 3832 |
3833 switch(op) { | 3833 switch(op) { |
3834 case LMUL: case LUMUL: /* case LDIV: */ case LUDIV: | 3834 case LMUL: case LUMUL: /* case LDIV: */ case LUDIV: |
3835 return ilog(v); | 3835 return ilog(v); |
3836 case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: | 3836 case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: |
3837 return 0<v&&v<=64; | 3837 return 0<v&&v<=64; |
3838 case LADD: | 3838 case LADD: |
3839 case LSUB: | 3839 case LSUB: |
3840 case LBOR: | 3840 case LBOR: |
3841 case LEOR: case LBAND: | 3841 case LEOR: case LBAND: |
3842 return (is_stage1_const(v,0)>0) | 3842 return (is_stage1_const(v,0)>0) |
3843 && (is_stage1_const(v>>32,0)>0); | 3843 && (is_stage1_const(v>>32,0)>0); |
3844 default: | 3844 default: |
3845 return 0; | 3845 return 0; |
3846 } | 3846 } |
3847 } | 3847 } |
3848 | 3848 |
3849 void | 3849 void |
3850 loprtc(int op,int creg,int e) | 3850 loprtc(int op,int creg,int e) |
3860 crn = register_name(creg); | 3860 crn = register_name(creg); |
3861 | 3861 |
3862 | 3862 |
3863 if (car(e)==LCONST) { v = lcadr(e); vh = lcadr(e)>>32; } | 3863 if (car(e)==LCONST) { v = lcadr(e); vh = lcadr(e)>>32; } |
3864 else if (car(e)==CONST) { | 3864 else if (car(e)==CONST) { |
3865 v = cadr(e); | 3865 v = cadr(e); |
3866 vh = (v<0)?-1:0; | 3866 vh = (v<0)?-1:0; |
3867 } | 3867 } |
3868 | 3868 |
3869 switch(op) { | 3869 switch(op) { |
3870 case LMUL: case LUMUL: | 3870 case LMUL: case LUMUL: |
3871 v=ilog(v); | 3871 v=ilog(v); |
3877 code_const(0,(creg)); | 3877 code_const(0,(creg)); |
3878 return; | 3878 return; |
3879 } else if (v>31) { | 3879 } else if (v>31) { |
3880 | 3880 |
3881 // 右シフト | 3881 // 右シフト |
3882 printf("\troti\t%s,%s,%d\n",crn,crn,96-v); | 3882 printf("\troti\t%s,%s,%d\n",crn,crn,96-v); |
3883 code_const(0,(creg)); | 3883 code_const(0,(creg)); |
3884 return; | 3884 return; |
3885 } | 3885 } |
3886 greg = get_register(); | 3886 greg = get_register(); |
3887 grn = register_name(greg); | 3887 grn = register_name(greg); |
3888 printf("\tshli\t%s, %s, %d\n",crn,crn,v); | 3888 printf("\tshli\t%s, %s, %d\n",crn,crn,v); |
3889 printf("\troti\t%s, %s, -%d\n",grn,crn,32-v); | 3889 printf("\troti\t%s, %s, -%d\n",grn,crn,32-v); |
3890 printf("\torc\t%s, %s,%s\n",crn,crn,grn); | 3890 printf("\torc\t%s, %s,%s\n",crn,crn,grn); |
3891 printf("\tshli\t%s, %s,%d\n",crn,crn,v); | 3891 printf("\tshli\t%s, %s,%d\n",crn,crn,v); |
3892 free_register(greg); | 3892 free_register(greg); |
3893 return; | 3893 return; |
3894 case LDIV: | 3894 case LDIV: |
3895 v=ilog(v); | 3895 v=ilog(v); |
3896 case LRSHIFT: | 3896 case LRSHIFT: |
3897 if (v==0) return; | 3897 if (v==0) return; |
3898 if (v==32) { | 3898 if (v==32) { |
3902 } else if (v>31) { | 3902 } else if (v>31) { |
3903 printf("\t\t%s, %s, asr #%d\n",crn,crn,v-32); | 3903 printf("\t\t%s, %s, asr #%d\n",crn,crn,v-32); |
3904 printf("\tshl\t%s, %s, 31\n",crn,crn); | 3904 printf("\tshl\t%s, %s, 31\n",crn,crn); |
3905 return; | 3905 return; |
3906 } | 3906 } |
3907 greg = get_register(); | 3907 greg = get_register(); |
3908 grn = register_name(greg); | 3908 grn = register_name(greg); |
3909 printf("\troti \t%s, %s, %d\n",crn,crn,v); | 3909 printf("\troti \t%s, %s, %d\n",crn,crn,v); |
3910 printf("\troti\t%s, %s, %d\n",grn,crn,160-v); | 3910 printf("\troti\t%s, %s, %d\n",grn,crn,160-v); |
3911 printf("\tor\t%s, %s,%s\n",crn,crn,grn); | 3911 printf("\tor\t%s, %s,%s\n",crn,crn,grn); |
3912 printf("\tshli\t%s, %s, %d\n",crn,crn,v); | 3912 printf("\tshli\t%s, %s, %d\n",crn,crn,v); |
3913 free_register(greg); | 3913 free_register(greg); |
3914 return; | 3914 return; |
3915 case LUDIV: | 3915 case LUDIV: |
3916 v=ilog(v); | 3916 v=ilog(v); |
3917 case LURSHIFT: | 3917 case LURSHIFT: |
3918 if (v==0) return; | 3918 if (v==0) return; |
3919 if (v==32) { | 3919 if (v==32) { |
3923 } else if (v>31) { | 3923 } else if (v>31) { |
3924 printf("\tmov\t%s, %s, lsr #%d\n",crn,crn,v-32); | 3924 printf("\tmov\t%s, %s, lsr #%d\n",crn,crn,v-32); |
3925 code_const(0,(creg)); | 3925 code_const(0,(creg)); |
3926 return; | 3926 return; |
3927 } | 3927 } |
3928 greg = get_register(); | 3928 greg = get_register(); |
3929 grn = register_name(greg); | 3929 grn = register_name(greg); |
3930 printf("\troti\t%s, %s, %d\n",grn,crn,96-v); | 3930 printf("\troti\t%s, %s, %d\n",grn,crn,96-v); |
3931 printf("\troti\t%s, %s, %d\n",crn,crn,v); | 3931 printf("\troti\t%s, %s, %d\n",crn,crn,v); |
3932 printf("\tor\t%s, %s,%s\n",crn,grn,crn); | 3932 printf("\tor\t%s, %s,%s\n",crn,grn,crn); |
3933 printf("\troti\t%s, %s, %d\n",crn,crn,v); | 3933 printf("\troti\t%s, %s, %d\n",crn,crn,v); |
3934 free_register(greg); | 3934 free_register(greg); |
3935 return; | 3935 return; |
3936 case LADD: | 3936 case LADD: |
3937 printf("\tadds\t%s, %s, #%d\n",crn,crn,v); | 3937 printf("\tadds\t%s, %s, #%d\n",crn,crn,v); |
3938 printf("\tadc\t%s, %s, #%d\n",crn,crn,vh); | 3938 printf("\tadc\t%s, %s, #%d\n",crn,crn,vh); |
3939 break; | 3939 break; |
3940 case LSUB: | 3940 case LSUB: |
3941 printf("\tsubs\t%s, %s, #%d\n",crn,crn,v); | 3941 printf("\tsubs\t%s, %s, #%d\n",crn,crn,v); |
3942 printf("\tsbc\t%s, %s, #%d\n",crn,crn,vh); | 3942 printf("\tsbc\t%s, %s, #%d\n",crn,crn,vh); |
3943 break; | 3943 break; |
3944 case LBAND: | 3944 case LBAND: |
3945 printf("\tandi\t%s, %s, %d\n",crn,crn,v); | 3945 printf("\tandi\t%s, %s, %d\n",crn,crn,v); |
3946 printf("\tandi\t%s, %s, %d\n",crn,crn,vh); | 3946 printf("\tandi\t%s, %s, %d\n",crn,crn,vh); |
3947 break; | 3947 break; |
3948 case LEOR: | 3948 case LEOR: |
3949 printf("\teor\t%s, %s, #%d\n",crn,crn,v); | 3949 printf("\teor\t%s, %s, #%d\n",crn,crn,v); |
3950 printf("\teor\t%s, %s, #%d\n",crn,crn,vh); | 3950 printf("\teor\t%s, %s, #%d\n",crn,crn,vh); |
3951 break; | 3951 break; |
3952 case LBOR: | 3952 case LBOR: |
3953 printf("\tori\t%s, %s, %d\n",crn,crn,v); | 3953 printf("\tori\t%s, %s, %d\n",crn,crn,v); |
3954 printf("\tori\t%s, %s, %d\n",crn,crn,vh); | 3954 printf("\tori\t%s, %s, %d\n",crn,crn,vh); |
3955 break; | 3955 break; |
3956 default: | 3956 default: |
3957 error(-1); | 3957 error(-1); |
3958 } | 3958 } |
3959 if (dx!=-1) free_register(dx); | 3959 if (dx!=-1) free_register(dx); |
3960 } | 3960 } |
3961 | 3961 |
3962 | 3962 |
3968 crn = register_name(reg0 = creg); | 3968 crn = register_name(reg0 = creg); |
3969 use_longlong(reg); | 3969 use_longlong(reg); |
3970 | 3970 |
3971 | 3971 |
3972 if (reg0!=(creg)) | 3972 if (reg0!=(creg)) |
3973 printf("\tori\t%s, %s, 0\n",crn,crn); | 3973 printf("\tori\t%s, %s, 0\n",crn,crn); |
3974 printf("\tshli\t%s, %s, 31\n",crn,crn); | 3974 printf("\tshli\t%s, %s, 31\n",crn,crn); |
3975 } | 3975 } |
3976 | 3976 |
3977 void | 3977 void |
3978 code_i2ull(int reg) | 3978 code_i2ull(int reg) |
3988 crn = register_name(reg0 = creg); | 3988 crn = register_name(reg0 = creg); |
3989 use_longlong(reg); | 3989 use_longlong(reg); |
3990 | 3990 |
3991 | 3991 |
3992 if (reg0!=(creg)) | 3992 if (reg0!=(creg)) |
3993 printf("\tori\t%s, %s, 0\n",crn,crn); | 3993 printf("\tori\t%s, %s, 0\n",crn,crn); |
3994 printf("\tmov\t%s, #0\n",crn); | 3994 printf("\tmov\t%s, #0\n",crn); |
3995 } | 3995 } |
3996 | 3996 |
3997 void | 3997 void |
3998 code_u2ull(int creg) | 3998 code_u2ull(int creg) |
4006 char *crn; | 4006 char *crn; |
4007 int reg0; | 4007 int reg0; |
4008 crn = register_name(reg0=creg); | 4008 crn = register_name(reg0=creg); |
4009 use_int(reg); | 4009 use_int(reg); |
4010 if (creg!=(reg0)) { | 4010 if (creg!=(reg0)) { |
4011 printf("\tori\t%s, %s, 0\n",register_name(creg),crn); | 4011 printf("\tori\t%s, %s, 0\n",register_name(creg),crn); |
4012 } | 4012 } |
4013 } | 4013 } |
4014 | 4014 |
4015 void | 4015 void |
4016 code_ll2u(int creg) | 4016 code_ll2u(int creg) |
4037 { | 4037 { |
4038 // fixdfdi$stub | 4038 // fixdfdi$stub |
4039 extern_conv("__fixdfdi"); | 4039 extern_conv("__fixdfdi"); |
4040 set_ireg(RET_REGISTER,0); | 4040 set_ireg(RET_REGISTER,0); |
4041 if (reg!=USE_CREG&®!=RET_REGISTER) { | 4041 if (reg!=USE_CREG&®!=RET_REGISTER) { |
4042 use_longlong(reg); | 4042 use_longlong(reg); |
4043 } | 4043 } |
4044 } | 4044 } |
4045 | 4045 |
4046 void | 4046 void |
4047 code_d2ull(int reg) | 4047 code_d2ull(int reg) |
4048 { | 4048 { |
4049 extern_conv("__fixunsdfdi"); | 4049 extern_conv("__fixunsdfdi"); |
4050 set_ireg(RET_REGISTER,0); | 4050 set_ireg(RET_REGISTER,0); |
4051 if (reg!=USE_CREG&®!=RET_REGISTER) { | 4051 if (reg!=USE_CREG&®!=RET_REGISTER) { |
4052 use_longlong(reg); | 4052 use_longlong(reg); |
4053 } | 4053 } |
4054 } | 4054 } |
4055 | 4055 |
4056 void | 4056 void |
4057 code_f2ll(int reg) | 4057 code_f2ll(int reg) |
4058 { | 4058 { |
4059 extern_conv("__fixsfdi"); | 4059 extern_conv("__fixsfdi"); |
4060 set_ireg(RET_REGISTER,0); | 4060 set_ireg(RET_REGISTER,0); |
4061 if (reg!=USE_CREG&®!=RET_REGISTER) { | 4061 if (reg!=USE_CREG&®!=RET_REGISTER) { |
4062 use_longlong(reg); | 4062 use_longlong(reg); |
4063 } | 4063 } |
4064 } | 4064 } |
4065 | 4065 |
4066 void | 4066 void |
4067 code_f2ull(int reg) | 4067 code_f2ull(int reg) |
4068 { | 4068 { |
4069 extern_conv("__fixunssfdi"); | 4069 extern_conv("__fixunssfdi"); |
4070 set_ireg(RET_REGISTER,0); | 4070 set_ireg(RET_REGISTER,0); |
4071 if (reg!=USE_CREG&®!=RET_REGISTER) { | 4071 if (reg!=USE_CREG&®!=RET_REGISTER) { |
4072 use_longlong(reg); | 4072 use_longlong(reg); |
4073 } | 4073 } |
4074 } | 4074 } |
4075 | 4075 |
4076 void | 4076 void |
4077 code_ll2d(int reg) | 4077 code_ll2d(int reg) |
4078 { | 4078 { |
4079 set_ireg(REGISTER_OPERAND,1); | 4079 set_ireg(REGISTER_OPERAND,1); |
4080 extern_conv("__floatdidf"); | 4080 extern_conv("__floatdidf"); |
4081 set_ireg(RET_REGISTER,0); | 4081 set_ireg(RET_REGISTER,0); |
4082 if (reg!=USE_CREG&®!=RET_REGISTER) | 4082 if (reg!=USE_CREG&®!=RET_REGISTER) |
4083 use_float(1,reg); | 4083 use_float(1,reg); |
4084 } | 4084 } |
4085 | 4085 |
4086 | 4086 |
4087 void | 4087 void |
4088 code_ll2f(int reg) | 4088 code_ll2f(int reg) |
4089 { | 4089 { |
4090 set_ireg(REGISTER_OPERAND,1); | 4090 set_ireg(REGISTER_OPERAND,1); |
4091 extern_conv("__floatdisf"); | 4091 extern_conv("__floatdisf"); |
4092 set_ireg(RET_REGISTER,0); | 4092 set_ireg(RET_REGISTER,0); |
4093 if (reg!=USE_CREG&®!=RET_REGISTER) | 4093 if (reg!=USE_CREG&®!=RET_REGISTER) |
4094 use_float(0,reg); | 4094 use_float(0,reg); |
4095 } | 4095 } |
4096 | 4096 |
4097 void | 4097 void |
4098 code_ull2d(int creg) | 4098 code_ull2d(int creg) |
4099 { | 4099 { |
4111 static void | 4111 static void |
4112 ladd(int dreg,int rreg,int v) // rreg = dreg + v | 4112 ladd(int dreg,int rreg,int v) // rreg = dreg + v |
4113 { | 4113 { |
4114 // v should be 8bit const with 2's shift | 4114 // v should be 8bit const with 2's shift |
4115 if (v>0) { | 4115 if (v>0) { |
4116 printf("\taddq\t%s, %s, #%d\n", | 4116 printf("\taddq\t%s, %s, #%d\n", |
4117 register_name(rreg),register_name(dreg), v); | 4117 register_name(rreg),register_name(dreg), v); |
4118 } else { | 4118 } else { |
4119 printf("\tsubq\t%s, %s, #%d\n", | 4119 printf("\tsubq\t%s, %s, #%d\n", |
4120 register_name(rreg),register_name(dreg), -v); | 4120 register_name(rreg),register_name(dreg), -v); |
4121 } | 4121 } |
4122 } | 4122 } |
4123 | 4123 |
4124 void | 4124 void |
4125 code_lpreinc(int e1,int e2,int reg) | 4125 code_lpreinc(int e1,int e2,int reg) |
4126 { | 4126 { |
4127 int dreg=-1,xreg=-1; | 4127 int dreg=-1,xreg=-1; |
4128 int dir=caddr(e1); | 4128 int dir=caddr(e1); |
4129 if (car(e2)==LREGISTER) { | 4129 if (car(e2)==LREGISTER) { |
4130 use_longlong(reg); | 4130 use_longlong(reg); |
4131 ladd(cadr(e2),cadr(e2),dir); | 4131 ladd(cadr(e2),cadr(e2),dir); |
4132 if (reg!=cadr(e2)) { | 4132 if (reg!=cadr(e2)) { |
4133 lmove(reg,cadr(e2)); | 4133 lmove(reg,cadr(e2)); |
4134 } | 4134 } |
4135 return; | 4135 return; |
4136 } | 4136 } |
4137 g_expr(e2); | 4137 g_expr(e2); |
4138 if(!is_int_reg(creg)) error(-1); | 4138 if(!is_int_reg(creg)) error(-1); |
4139 emit_push(); | 4139 emit_push(); |
4140 if (reg==USE_CREG) { | 4140 if (reg==USE_CREG) { |
4141 dreg=get_lregister(); if (!dreg) error(-1); | 4141 dreg=get_lregister(); if (!dreg) error(-1); |
4142 set_ireg(dreg,0); // free old lreg==creg | 4142 set_ireg(dreg,0); // free old lreg==creg |
4143 } else { | 4143 } else { |
4144 dreg = reg; | 4144 dreg = reg; |
4145 } | 4145 } |
4146 xreg = emit_pop(0); | 4146 xreg = emit_pop(0); |
4147 lload(xreg,dreg,0); | 4147 lload(xreg,dreg,0); |
4155 code_lpostinc(int e1,int e2,int reg) | 4155 code_lpostinc(int e1,int e2,int reg) |
4156 { | 4156 { |
4157 int dreg,nreg,xreg; | 4157 int dreg,nreg,xreg; |
4158 int dir=caddr(e1); | 4158 int dir=caddr(e1); |
4159 if (car(e2)==LREGISTER) { | 4159 if (car(e2)==LREGISTER) { |
4160 use_longlong(reg); | 4160 use_longlong(reg); |
4161 lmove(reg,cadr(e2)); | 4161 lmove(reg,cadr(e2)); |
4162 ladd(cadr(e2),cadr(e2),dir); | 4162 ladd(cadr(e2),cadr(e2),dir); |
4163 return; | 4163 return; |
4164 } | 4164 } |
4165 g_expr(e2); | 4165 g_expr(e2); |
4166 if(!is_int_reg(creg)) error(-1); | 4166 if(!is_int_reg(creg)) error(-1); |
4167 emit_push(); | 4167 emit_push(); |
4168 nreg=get_lregister(); if (!nreg) error(-1); | 4168 nreg=get_lregister(); if (!nreg) error(-1); |
4169 if (reg==USE_CREG) { | 4169 if (reg==USE_CREG) { |
4170 dreg=get_lregister(); if (!dreg) error(-1); | 4170 dreg=get_lregister(); if (!dreg) error(-1); |
4171 set_ireg(dreg,0); // free old lreg==creg | 4171 set_ireg(dreg,0); // free old lreg==creg |
4172 } else { | 4172 } else { |
4173 dreg = reg; | 4173 dreg = reg; |
4174 } | 4174 } |
4175 xreg = emit_pop(0); | 4175 xreg = emit_pop(0); |
4176 lload(xreg,dreg,0); | 4176 lload(xreg,dreg,0); |
4177 ladd(dreg,nreg,dir); | 4177 ladd(dreg,nreg,dir); |
4178 lstore(xreg,nreg); | 4178 lstore(xreg,nreg); |
4191 if (!is_int_reg(creg)) error(-1); | 4191 if (!is_int_reg(creg)) error(-1); |
4192 edx = creg; | 4192 edx = creg; |
4193 emit_push(); | 4193 emit_push(); |
4194 use_longlong(reg); | 4194 use_longlong(reg); |
4195 if ((creg)==edx) { | 4195 if ((creg)==edx) { |
4196 edx0 = get_register(); if(!edx0) error(-1); | 4196 edx0 = get_register(); if(!edx0) error(-1); |
4197 printf("## lassop\n\tori\t%s, %s, 0\n",register_name(edx0), | 4197 printf("## lassop\n\tori\t%s, %s, 0\n",register_name(edx0), |
4198 register_name(edx)); | 4198 register_name(edx)); |
4199 edx = edx0; | 4199 edx = edx0; |
4200 } | 4200 } |
4201 lload(edx,reg,0); | 4201 lload(edx,reg,0); |
4202 // free_register(edx); don't do this, it will free pushed register | 4202 // free_register(edx); don't do this, it will free pushed register |
4203 ltosop(op,reg,xreg); // loprtc? | 4203 ltosop(op,reg,xreg); // loprtc? |
4204 emit_lpop_free(xreg); | 4204 emit_lpop_free(xreg); |
4205 use_reg(reg); | 4205 use_reg(reg); |
4206 edx = emit_pop(0); | 4206 edx = emit_pop(0); |
4207 code_lassign(edx,reg); | 4207 code_lassign(edx,reg); |
4208 emit_pop_free(edx); | 4208 emit_pop_free(edx); |
4209 if (edx0!=-1) | 4209 if (edx0!=-1) |
4210 free_register(edx0); | 4210 free_register(edx0); |
4211 if (reg!=creg) | 4211 if (reg!=creg) |
4212 free_register(reg); | 4212 free_register(reg); |
4213 } | 4213 } |
4214 | 4214 |
4215 void | 4215 void |
4216 code_register_lassop(int reg,int op) { | 4216 code_register_lassop(int reg,int op) { |
4217 // reg op = pop() | 4217 // reg op = pop() |
4230 for(i=0;i<reg_sp;i++) { | 4230 for(i=0;i<reg_sp;i++) { |
4231 if ((reg=reg_stack[i])>=0) { | 4231 if ((reg=reg_stack[i])>=0) { |
4232 code_assign_lvar( | 4232 code_assign_lvar( |
4233 (reg_stack[i]=new_lvar(SIZE_OF_VECTOR)),reg,0); | 4233 (reg_stack[i]=new_lvar(SIZE_OF_VECTOR)),reg,0); |
4234 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; | 4234 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; |
4235 free_register(reg); | 4235 free_register(reg); |
4236 } | 4236 } |
4237 } | 4237 } |
4238 } | 4238 } |
4239 | 4239 |
4240 void | 4240 void |
4241 emit_lib(char *p[]) | 4241 emit_lib(char *p[]) |
4242 { | 4242 { |
4243 while(*p) { | 4243 while(*p) { |
4244 printf("%s\n",*p++); | 4244 printf("%s\n",*p++); |
4245 } | 4245 } |
4246 } | 4246 } |
4247 | 4247 |
4248 void | 4248 void |
4249 code_closing() | 4249 code_closing() |
4267 regs[csvalue] = regsv; | 4267 regs[csvalue] = regsv; |
4268 | 4268 |
4269 code_add(t,-min,csvalue); | 4269 code_add(t,-min,csvalue); |
4270 switch(delta) { | 4270 switch(delta) { |
4271 case 1: | 4271 case 1: |
4272 code_cmpdimm(max-min,t,dlabel,-1); | 4272 code_cmpdimm(max-min,t,dlabel,-1); |
4273 printf("\tldrls\tpc, [pc, %s, asl #2]\n",trn); | 4273 printf("\tldrls\tpc, [pc, %s, asl #2]\n",trn); |
4274 break; | 4274 break; |
4275 case 2: | 4275 case 2: |
4276 printf("\ttst\t%s, #1\n",trn); | 4276 printf("\ttst\t%s, #1\n",trn); |
4277 printf("\tbr\t.L%d\n",dlabel); | 4277 printf("\tbr\t.L%d\n",dlabel); |
4278 code_cmpdimm(max-min,t,dlabel,-1); | 4278 code_cmpdimm(max-min,t,dlabel,-1); |
4279 printf("\tldrls\tpc, [pc, %s, asl #1]\n",trn); break; | 4279 printf("\tldrls\tpc, [pc, %s, asl #1]\n",trn); break; |
4280 break; | 4280 break; |
4281 case 4: | 4281 case 4: |
4282 printf("\ttst\t%s, #3\n",trn); | 4282 printf("\ttst\t%s, #3\n",trn); |
4283 printf("\tbr\t.L%d\n",dlabel); | 4283 printf("\tbr\t.L%d\n",dlabel); |
4284 code_cmpdimm(max-min,t,dlabel,-1); | 4284 code_cmpdimm(max-min,t,dlabel,-1); |
4285 printf("\tldrls\tpc, [pc, %s]\n",trn); break; | 4285 printf("\tldrls\tpc, [pc, %s]\n",trn); break; |
4286 break; | 4286 break; |
4287 default: | 4287 default: |
4288 error(-1); | 4288 error(-1); |
4289 } | 4289 } |
4290 printf("\thbr\t.L%d\n",dlabel); | 4290 printf("\thbr\t.L%d\n",dlabel); |
4291 | 4291 |
4292 free_register(t); | 4292 free_register(t); |
4293 } | 4293 } |
4322 | 4322 |
4323 static void | 4323 static void |
4324 emit_asm_operand(int rstr) | 4324 emit_asm_operand(int rstr) |
4325 { | 4325 { |
4326 if (car(rstr)==REGISTER) { | 4326 if (car(rstr)==REGISTER) { |
4327 printf("%s",register_name(cadr(rstr))); | 4327 printf("%s",register_name(cadr(rstr))); |
4328 } else if (car(rstr)==CONST) { | 4328 } else if (car(rstr)==CONST) { |
4329 printf("%d",cadr(rstr)); | 4329 printf("%d",cadr(rstr)); |
4330 } else if (car(rstr)==FNAME) { | 4330 } else if (car(rstr)==FNAME) { |
4331 printf("%s",ncaddr(rstr)->nm); | 4331 printf("%s",ncaddr(rstr)->nm); |
4332 } else if (car(rstr)==LABEL) { | 4332 } else if (car(rstr)==LABEL) { |
4333 printf(".L%d",cadr(rstr)); | 4333 printf(".L%d",cadr(rstr)); |
4334 } else { | 4334 } else { |
4335 error(-1); | 4335 error(-1); |
4336 } | 4336 } |
4337 } | 4337 } |
4338 | 4338 |
4339 /* | 4339 /* |
4340 prepare asm operands | 4340 prepare asm operands |
4360 int val; | 4360 int val; |
4361 int clobber = 0; | 4361 int clobber = 0; |
4362 | 4362 |
4363 printf("## constraint %s\n",p); | 4363 printf("## constraint %s\n",p); |
4364 if (*p=='=') { | 4364 if (*p=='=') { |
4365 // output register | 4365 // output register |
4366 p++; | 4366 p++; |
4367 } | 4367 } |
4368 if (*p=='&') { | 4368 if (*p=='&') { |
4369 // earlyclobber | 4369 // earlyclobber |
4370 p++; | 4370 p++; |
4371 clobber = 1; | 4371 clobber = 1; |
4372 } | 4372 } |
4373 c = *p; | 4373 c = *p; |
4374 if (c=='r') { | 4374 if (c=='r') { |
4375 if (mode==ASM_INPUT) { | 4375 if (mode==ASM_INPUT) { |
4376 for(;repl0;repl0 = cadr(repl0)) { | 4376 for(;repl0;repl0 = cadr(repl0)) { |
4377 if (car(car(repl0))==REGISTER && caddr(repl0)==0) { | 4377 if (car(car(repl0))==REGISTER && caddr(repl0)==0) { |
4378 r = cadr(car(repl0)); | 4378 r = cadr(car(repl0)); |
4379 caddr(repl0) = ASM_USED; | 4379 caddr(repl0) = ASM_USED; |
4380 break; | 4380 break; |
4381 } | 4381 } |
4382 } | 4382 } |
4383 r = get_register(); | 4383 r = get_register(); |
4384 } else { | 4384 } else { |
4385 r = get_register(); | 4385 r = get_register(); |
4386 } | 4386 } |
4387 repl = list3(list2(REGISTER,r),repl,clobber); | 4387 repl = list3(list2(REGISTER,r),repl,clobber); |
4388 } else if (c=='m') { | 4388 } else if (c=='m') { |
4389 repl = list3(list2(0,0),repl,clobber); | 4389 repl = list3(list2(0,0),repl,clobber); |
4390 } else if (c=='i') { | 4390 } else if (c=='i') { |
4391 if (car(e1)==GVAR) { | 4391 if (car(e1)==GVAR) { |
4392 e1=list3n(FNAME,0,ncaddr(e1)); | 4392 e1=list3n(FNAME,0,ncaddr(e1)); |
4393 } else if (car(e1)==FNAME) { | 4393 } else if (car(e1)==FNAME) { |
4394 e1=list3n(FNAME,0,ncaddr(e1)); | 4394 e1=list3n(FNAME,0,ncaddr(e1)); |
4395 } else if (car(e1)==STRING) { | 4395 } else if (car(e1)==STRING) { |
4396 val = emit_string_label(); | 4396 val = emit_string_label(); |
4397 ascii(ncaddr(e1)->nm); | 4397 ascii(ncaddr(e1)->nm); |
4398 e1=list2(LABEL,val); | 4398 e1=list2(LABEL,val); |
4399 } else if (car(e1)==CONST) { | 4399 } else if (car(e1)==CONST) { |
4400 } else error(-1); | 4400 } else error(-1); |
4401 repl = list3(e1,repl,clobber); | 4401 repl = list3(e1,repl,clobber); |
4402 } else if (digit(c)) { | 4402 } else if (digit(c)) { |
4403 val = 0; | 4403 val = 0; |
4404 do { val = val*10 + c-'0'; } while (digit(c=*p++)); | 4404 do { val = val*10 + c-'0'; } while (digit(c=*p++)); |
4405 if (val>MAX_ASM_REG) error(-1); // too large register | 4405 if (val>MAX_ASM_REG) error(-1); // too large register |
4406 if (n-val<0) error(-1); | 4406 if (n-val<0) error(-1); |
4407 repl = list3(car(nth(n-val-1,repl0)),repl,clobber); | 4407 repl = list3(car(nth(n-val-1,repl0)),repl,clobber); |
4408 } else error(-1); | 4408 } else error(-1); |
4409 return repl; | 4409 return repl; |
4410 } | 4410 } |
4411 | 4411 |
4412 void | 4412 void |
4413 code_free_asm_operand(int repl) | 4413 code_free_asm_operand(int repl) |
4414 { | 4414 { |
4415 for(;repl;repl=cadr(repl)) { | 4415 for(;repl;repl=cadr(repl)) { |
4416 if (car(car(repl))==REGISTER) | 4416 if (car(car(repl))==REGISTER) |
4417 free_register(cadr(car(repl))); | 4417 free_register(cadr(car(repl))); |
4418 } | 4418 } |
4419 } | 4419 } |
4420 | 4420 |
4421 | 4421 |
4422 extern void | 4422 extern void |
4428 | 4428 |
4429 text_mode(2); | 4429 text_mode(2); |
4430 c = *asm_str; | 4430 c = *asm_str; |
4431 if (c!='\t'&&c!=' ') printf("\t"); | 4431 if (c!='\t'&&c!=' ') printf("\t"); |
4432 for(i=0;repl && i<MAX_ASM_REG;i++) { | 4432 for(i=0;repl && i<MAX_ASM_REG;i++) { |
4433 reg[i] = car(repl); | 4433 reg[i] = car(repl); |
4434 repl = cadr(repl); | 4434 repl = cadr(repl); |
4435 } | 4435 } |
4436 p = asm_str; | 4436 p = asm_str; |
4437 while((c = *p++)) { | 4437 while((c = *p++)) { |
4438 if (c=='%') { | 4438 if (c=='%') { |
4439 c = *p++; | 4439 c = *p++; |
4440 if (!c) { break; | 4440 if (!c) { break; |
4441 } else if (c=='%') { | 4441 } else if (c=='%') { |
4442 printf("%%"); continue; | 4442 printf("%%"); continue; |
4443 } else if (!digit(c)) { | 4443 } else if (!digit(c)) { |
4444 printf("%%%c",c); continue; | 4444 printf("%%%c",c); continue; |
4445 } | 4445 } |
4446 val = 0; | 4446 val = 0; |
4447 do { val = val*10 + c-'0'; } while (digit(c=*p++)) ; | 4447 do { val = val*10 + c-'0'; } while (digit(c=*p++)) ; |
4448 p--; | 4448 p--; |
4449 if (val>MAX_ASM_REG) error(-1); // too large register | 4449 if (val>MAX_ASM_REG) error(-1); // too large register |
4450 rstr = reg[val]; | 4450 rstr = reg[val]; |
4451 emit_asm_operand(rstr); | 4451 emit_asm_operand(rstr); |
4452 } else { | 4452 } else { |
4453 printf("%c",c); | 4453 printf("%c",c); |
4454 } | 4454 } |
4455 } | 4455 } |
4456 printf("\n"); | 4456 printf("\n"); |
4457 } | 4457 } |
4458 | 4458 |
4459 #endif | 4459 #endif |
4463 | 4463 |
4464 /* bit field alignment calcuration */ | 4464 /* bit field alignment calcuration */ |
4465 | 4465 |
4466 static void | 4466 static void |
4467 set_bitsz(int type,int *pbitpos, int *pbitsize, | 4467 set_bitsz(int type,int *pbitpos, int *pbitsize, |
4468 int *psign,int *pbitsz,int *palign,int *pl) | 4468 int *psign,int *pbitsz,int *palign,int *pl) |
4469 { | 4469 { |
4470 int sign=0,bitsz=0; | 4470 int sign=0,bitsz=0; |
4471 int align=0,l=0; | 4471 int align=0,l=0; |
4472 switch(cadr(type)) { /* value type */ | 4472 switch(cadr(type)) { /* value type */ |
4473 case INT: sign=1; break; | 4473 case INT: sign=1; break; |
4474 case UNSIGNED: break; | 4474 case UNSIGNED: break; |
4475 case CHAR: sign=1; break; | 4475 case CHAR: sign=1; break; |
4476 case UCHAR: break; | 4476 case UCHAR: break; |
4477 case SHORT: sign=1; break; | 4477 case SHORT: sign=1; break; |
4478 case USHORT: sign=1; break; | 4478 case USHORT: sign=1; break; |
4479 case LONGLONG: sign=1; l=1; break; | 4479 case LONGLONG: sign=1; l=1; break; |
4480 case ULONGLONG: l=1; break; | 4480 case ULONGLONG: l=1; break; |
4481 default: error(-1); | 4481 default: error(-1); |
4482 } | 4482 } |
4483 if (car(caddr(type))>0) { /* store type */ | 4483 if (car(caddr(type))>0) { /* store type */ |
4484 if (car(car(caddr(type)))==STRUCT) { | 4484 if (car(car(caddr(type)))==STRUCT) { |
4485 bitsz=64+32; align=4; l=2; | 4485 bitsz=64+32; align=4; l=2; |
4486 } else error(-1); | 4486 } else error(-1); |
4487 } else { | 4487 } else { |
4488 switch(car(caddr(type))) { | 4488 switch(car(caddr(type))) { |
4489 case INT: bitsz=32; align=4; break; | 4489 case INT: bitsz=32; align=4; break; |
4490 case UNSIGNED: bitsz=32; align=4; break; | 4490 case UNSIGNED: bitsz=32; align=4; break; |
4491 case CHAR: bitsz= 8; align=1; break; | 4491 case CHAR: bitsz= 8; align=1; break; |
4492 case UCHAR: bitsz= 8; align=1; break; | 4492 case UCHAR: bitsz= 8; align=1; break; |
4493 case SHORT: bitsz=16; align=2; break; | 4493 case SHORT: bitsz=16; align=2; break; |
4494 case USHORT: bitsz=16; align=2; break; | 4494 case USHORT: bitsz=16; align=2; break; |
4495 case LONGLONG: bitsz=64; align=4; l=1; break; | 4495 case LONGLONG: bitsz=64; align=4; l=1; break; |
4496 case ULONGLONG: bitsz=64; align=4; l=1; break; | 4496 case ULONGLONG: bitsz=64; align=4; l=1; break; |
4497 default: error(-1); | 4497 default: error(-1); |
4498 } | 4498 } |
4499 } | 4499 } |
4500 *pbitpos = cadr(caddr(type)); | 4500 *pbitpos = cadr(caddr(type)); |
4501 *pbitsize = caddr(caddr(type)); | 4501 *pbitsize = caddr(caddr(type)); |
4502 *psign = sign; | 4502 *psign = sign; |
4503 *pbitsz = bitsz; | 4503 *pbitsz = bitsz; |
4525 | 4525 |
4526 if (bitsize>bitsz) { error(BTERR); bitsize = bitsz; } | 4526 if (bitsize>bitsz) { error(BTERR); bitsize = bitsz; } |
4527 | 4527 |
4528 /* bfd means previous bit field bit offset */ | 4528 /* bfd means previous bit field bit offset */ |
4529 if (bitpos) { | 4529 if (bitpos) { |
4530 /* previous field is bit field and spaces may remain */ | 4530 /* previous field is bit field and spaces may remain */ |
4531 /* calc previsous offset */ | 4531 /* calc previsous offset */ |
4532 offset-=(bitpos+7)/8; | 4532 offset-=(bitpos+7)/8; |
4533 | 4533 |
4534 #ifdef NON_ALIGNED_BFD | 4534 #ifdef NON_ALIGNED_BFD |
4535 /* code for non-aligned non-hole bit-field */ | 4535 /* code for non-aligned non-hole bit-field */ |
4536 | 4536 |
4537 /* remove extra previous offset from bitpos */ | 4537 /* remove extra previous offset from bitpos */ |
4538 while(bitpos>align*8) { | 4538 while(bitpos>align*8) { |
4539 i = ((offset+(align))&~(align-1))-offset; | 4539 i = ((offset+(align))&~(align-1))-offset; |
4540 offset+=i; bitpos-=i*8; | 4540 offset+=i; bitpos-=i*8; |
4541 } | 4541 } |
4542 if (bitpos+bitsize > bitsz) { | 4542 if (bitpos+bitsize > bitsz) { |
4543 int stype=UNSIGNED; | 4543 int stype=UNSIGNED; |
4544 | 4544 |
4545 /* rewind extra previous offset */ | 4545 /* rewind extra previous offset */ |
4546 bitpos = *bfd; offset=*poffset; | 4546 bitpos = *bfd; offset=*poffset; |
4547 offset-=(bitpos+7)/8; | 4547 offset-=(bitpos+7)/8; |
4548 | 4548 |
4549 /* extend store type to allow |---===|===---| */ | 4549 /* extend store type to allow |---===|===---| */ |
4550 switch(car(caddr(type))) { | 4550 switch(car(caddr(type))) { |
4551 case INT: case UNSIGNED: | 4551 case INT: case UNSIGNED: |
4552 stype=ULONGLONG; align=4; break; | 4552 stype=ULONGLONG; align=4; break; |
4553 case CHAR: case UCHAR: | 4553 case CHAR: case UCHAR: |
4554 stype=USHORT; align=2; break; | 4554 stype=USHORT; align=2; break; |
4555 case SHORT: case USHORT: | 4555 case SHORT: case USHORT: |
4556 stype=UNSIGNED; align=4; break; | 4556 stype=UNSIGNED; align=4; break; |
4557 case ULONGLONG: case LONGLONG: | 4557 case ULONGLONG: case LONGLONG: |
4558 /* dummy struct type. fields are never used */ | 4558 /* dummy struct type. fields are never used */ |
4559 stype=list4(STRUCT,12,0,0);align=4;break; | 4559 stype=list4(STRUCT,12,0,0);align=4;break; |
4560 default: error(-1); | 4560 default: error(-1); |
4561 } | 4561 } |
4562 /* remove extra previous offset from bitpos again */ | 4562 /* remove extra previous offset from bitpos again */ |
4563 while(bitpos>align*8) { | 4563 while(bitpos>align*8) { |
4564 i = ((offset+(align))&~(align-1))-offset; | 4564 i = ((offset+(align))&~(align-1))-offset; |
4565 offset+=i; bitpos-=i*8; | 4565 offset+=i; bitpos-=i*8; |
4566 } | 4566 } |
4567 bitsz = size(stype)*8; | 4567 bitsz = size(stype)*8; |
4568 /* fix store type */ | 4568 /* fix store type */ |
4569 car(caddr(type)) = stype; | 4569 car(caddr(type)) = stype; |
4570 } | 4570 } |
4571 #endif | 4571 #endif |
4572 | 4572 |
4573 /* previous remaining bit space can contain this type? */ | 4573 /* previous remaining bit space can contain this type? */ |
4574 i= offset; | 4574 i= offset; |
4575 for(l = bitpos;l>0;l -= 8,i++) { | 4575 for(l = bitpos;l>0;l -= 8,i++) { |
4576 if ((i & (align-1))==0 && l+bitsize <= bitsz) { | 4576 if ((i & (align-1))==0 && l+bitsize <= bitsz) { |
4577 /* alignment is correct and space remains */ | 4577 /* alignment is correct and space remains */ |
4578 *poffset=offset=i; | 4578 *poffset=offset=i; |
4579 i = l+bitsize; | 4579 i = l+bitsize; |
4580 *bfd = (i==bitsz)?0:i; | 4580 *bfd = (i==bitsz)?0:i; |
4581 *sz = (i+7)/8; | 4581 *sz = (i+7)/8; |
4582 #ifdef BITPOS_DEBUG | 4582 #ifdef BITPOS_DEBUG |
4583 printf("## %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset); | 4583 printf("## %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset); |
4584 #endif | 4584 #endif |
4585 return l; | 4585 return l; |
4586 } | 4586 } |
4587 } | 4587 } |
4588 } | 4588 } |
4589 | 4589 |
4590 /* first bit-field or no remaining bits */ | 4590 /* first bit-field or no remaining bits */ |
4591 | 4591 |
4592 if ((i=(offset & (align-1)))) { | 4592 if ((i=(offset & (align-1)))) { |
4593 *poffset = (offset += (align-i)); | 4593 *poffset = (offset += (align-i)); |
4594 } | 4594 } |
4595 bitpos = 0; | 4595 bitpos = 0; |
4596 *bfd = (bitsize==bitsz)?0:bitsize; | 4596 *bfd = (bitsize==bitsz)?0:bitsize; |
4597 *sz = (bitsize+7)/8; | 4597 *sz = (bitsize+7)/8; |
4598 #ifdef BITPOS_DEBUG | 4598 #ifdef BITPOS_DEBUG |
4614 size = bitsz/8; | 4614 size = bitsz/8; |
4615 // printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); | 4615 // printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); |
4616 /* this implementation returns -1 for int i:1; */ | 4616 /* this implementation returns -1 for int i:1; */ |
4617 if (l==1) { | 4617 if (l==1) { |
4618 #if LONGLONG_CODE | 4618 #if LONGLONG_CODE |
4619 // use_int(adr); | 4619 // use_int(adr); |
4620 use_longlong(reg); | 4620 use_longlong(reg); |
4621 lload(adr,reg,0); | 4621 lload(adr,reg,0); |
4622 /* shift left */ | 4622 /* shift left */ |
4623 if ((i=bitsz-bitsize-bitpos)) | 4623 if ((i=bitsz-bitsize-bitpos)) |
4624 loprtc(LLSHIFT,reg,list2(CONST,i)); | 4624 loprtc(LLSHIFT,reg,list2(CONST,i)); |
4625 /* shift right */ | 4625 /* shift right */ |
4626 if ((i=bitsz-bitsize)) | 4626 if ((i=bitsz-bitsize)) |
4627 loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); | 4627 loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); |
4628 } else if (l==2) { /* three int container */ | 4628 } else if (l==2) { /* three int container */ |
4629 int lvalue; | 4629 int lvalue; |
4630 // use_int(adr); | 4630 // use_int(adr); |
4631 use_longlong(reg); | 4631 use_longlong(reg); |
4632 lvalue = get_register(); | 4632 lvalue = get_register(); |
4633 code_register(adr,lvalue); adr = lvalue; | 4633 code_register(adr,lvalue); adr = lvalue; |
4634 /* | 4634 /* |
4635 | 4635 |
4636 <-----bitsize---------------> | 4636 <-----bitsize---------------> |
4637 hhhhhh mmmmmmmmmmmm lllllll | 4637 hhhhhh mmmmmmmmmmmm lllllll |
4638 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh | 4638 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh |
4644 rest >> = b; | 4644 rest >> = b; |
4645 rest << = a; (b>a) ==> rest >> (b-a) | 4645 rest << = a; (b>a) ==> rest >> (b-a) |
4646 (64+32-bitsize -bitpos - (bitsz-bitsize)) | 4646 (64+32-bitsize -bitpos - (bitsz-bitsize)) |
4647 = 64+32 -bitsz -bitbpos | 4647 = 64+32 -bitsz -bitbpos |
4648 */ | 4648 */ |
4649 /* load hhhhh */ | 4649 /* load hhhhh */ |
4650 code_ld(cload(0,0),(reg),SIZE_OF_INT*2,adr,cext_at(0,0)); | 4650 code_ld(cload(0,0),(reg),SIZE_OF_INT*2,adr,cext_at(0,0)); |
4651 /* load mmmmmm */ | 4651 /* load mmmmmm */ |
4652 code_ld(cload(0,0),(reg),SIZE_OF_INT,adr,cext_at(0,0)); | 4652 code_ld(cload(0,0),(reg),SIZE_OF_INT,adr,cext_at(0,0)); |
4653 i = 64-(bitsize-(32-bitpos)); | 4653 i = 64-(bitsize-(32-bitpos)); |
4654 loprtc(LLSHIFT,reg,list2(CONST,i)); | 4654 loprtc(LLSHIFT,reg,list2(CONST,i)); |
4655 if (i<0||64<=i) error(-1); | 4655 if (i<0||64<=i) error(-1); |
4656 /* load lllll */ | 4656 /* load lllll */ |
4657 code_ld(cload(0,0),adr,0,adr,cext_at(0,0)); | 4657 code_ld(cload(0,0),adr,0,adr,cext_at(0,0)); |
4658 i = (bitsize-(32-bitpos))-32; | 4658 i = (bitsize-(32-bitpos))-32; |
4659 oprtc(URSHIFT,adr,list2(CONST,i)); | 4659 oprtc(URSHIFT,adr,list2(CONST,i)); |
4660 if (i<0||32<=i) error(-1); | 4660 if (i<0||32<=i) error(-1); |
4661 printf("\tadd\t%s,%s,%s\n", | 4661 printf("\tadd\t%s,%s,%s\n", |
4662 register_name((reg)), | 4662 register_name((reg)), |
4663 register_name((reg)), | 4663 register_name((reg)), |
4664 register_name(adr)); | 4664 register_name(adr)); |
4665 i = 64-bitsize; | 4665 i = 64-bitsize; |
4666 loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); | 4666 loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); |
4667 if (i<0||64<=i) error(-1); | 4667 if (i<0||64<=i) error(-1); |
4668 free_register(adr); | 4668 free_register(adr); |
4669 #endif | 4669 #endif |
4670 } else { | 4670 } else { |
4671 // use_int(adr); | 4671 // use_int(adr); |
4672 use_int(reg); | 4672 use_int(reg); |
4673 code_ld(cload(size,sign),reg,0,adr,cext_at(0,0)); | 4673 code_ld(cload(size,sign),reg,0,adr,cext_at(0,0)); |
4674 /* shift left */ | 4674 /* shift left */ |
4675 if ((i=32-bitsize-bitpos)) | 4675 if ((i=32-bitsize-bitpos)) |
4676 oprtc(LSHIFT,reg,list2(CONST,i)); | 4676 oprtc(LSHIFT,reg,list2(CONST,i)); |
4677 /* shift right */ | 4677 /* shift right */ |
4678 if ((i=32-bitsize)) | 4678 if ((i=32-bitsize)) |
4679 oprtc(sign?RSHIFT:URSHIFT,reg,list2(CONST,i)); | 4679 oprtc(sign?RSHIFT:URSHIFT,reg,list2(CONST,i)); |
4680 } | 4680 } |
4681 } | 4681 } |
4682 | 4682 |
4683 /* bit field replacement */ | 4683 /* bit field replacement */ |
4684 | 4684 |
4685 static void | 4685 static void |
4686 make_mask_and_or(int mask,int tmp,char *trn,char *crn,char *lrn) | 4686 make_mask_and_or(int mask,int tmp,char *trn,char *crn,char *lrn) |
4687 { | 4687 { |
4688 // printf("## mask 0x%08x ~0x%08x\n",mask,~mask); | 4688 // printf("## mask 0x%08x ~0x%08x\n",mask,~mask); |
4689 code_const(~mask,tmp); | 4689 code_const(~mask,tmp); |
4690 printf("\tor\t%s, %s, %s\n",trn,crn,trn); | 4690 printf("\tor\t%s, %s, %s\n",trn,crn,trn); |
4691 /* do conjunction */ | 4691 /* do conjunction */ |
4692 printf("\tand\t%s, %s, %s\n",lrn,trn,lrn); | 4692 printf("\tand\t%s, %s, %s\n",lrn,trn,lrn); |
4693 /* make or-mask */ | 4693 /* make or-mask */ |
4694 code_const(mask,tmp); | 4694 code_const(mask,tmp); |
4695 printf("\tand\t%s, %s, %s\n",trn,crn,trn); | 4695 printf("\tand\t%s, %s, %s\n",trn,crn,trn); |
4696 /* do disjunction */ | 4696 /* do disjunction */ |
4697 printf("\tor\t%s, %s, %s\n",crn,trn,lrn); | 4697 printf("\tor\t%s, %s, %s\n",crn,trn,lrn); |
4698 } | 4698 } |
4699 | 4699 |
4700 extern void | 4700 extern void |
4701 code_bit_replace(int adr,int value,int type) | 4701 code_bit_replace(int adr,int value,int type) |
4702 { | 4702 { |
4708 set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); | 4708 set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); |
4709 size = bitsz/8; | 4709 size = bitsz/8; |
4710 // printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); | 4710 // printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); |
4711 if (l==1) { | 4711 if (l==1) { |
4712 #if LONGLONG_CODE | 4712 #if LONGLONG_CODE |
4713 int tmp2; | 4713 int tmp2; |
4714 // use_int(adr); | 4714 // use_int(adr); |
4715 lvalue = get_lregister(); | 4715 lvalue = get_lregister(); |
4716 tmp2 = get_register(); | 4716 tmp2 = get_register(); |
4717 code_register(adr,tmp2); adr = tmp2; | 4717 code_register(adr,tmp2); adr = tmp2; |
4718 lload(adr,lvalue,0); | 4718 lload(adr,lvalue,0); |
4719 use_longlong(value); | 4719 use_longlong(value); |
4720 crn = register_name(value); | 4720 crn = register_name(value); |
4721 lrn = register_name(lvalue); | 4721 lrn = register_name(lvalue); |
4722 /* shift left */ | 4722 /* shift left */ |
4723 if (bitpos) | 4723 if (bitpos) |
4724 loprtc(LLSHIFT,value,list2(CONST,bitpos)); | 4724 loprtc(LLSHIFT,value,list2(CONST,bitpos)); |
4725 trn = register_name(tmp = get_register()); | 4725 trn = register_name(tmp = get_register()); |
4726 if (bitpos+bitsize>=32) { | 4726 if (bitpos+bitsize>=32) { |
4727 /* make and-mask upper */ | 4727 /* make and-mask upper */ |
4728 mask = make_mask(64-bitpos-bitsize,bitpos>=32?63-bitpos:31); | 4728 mask = make_mask(64-bitpos-bitsize,bitpos>=32?63-bitpos:31); |
4729 make_mask_and_or(mask,tmp,trn,crn,lrn); | 4729 make_mask_and_or(mask,tmp,trn,crn,lrn); |
4730 } | 4730 } |
4731 crn = register_name(value); | 4731 crn = register_name(value); |
4732 lrn = register_name(lvalue); | 4732 lrn = register_name(lvalue); |
4733 if (bitpos<32) { | 4733 if (bitpos<32) { |
4734 /* make and-mask lower */ | 4734 /* make and-mask lower */ |
4735 mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); | 4735 mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); |
4736 make_mask_and_or(mask,tmp,trn,crn,lrn); | 4736 make_mask_and_or(mask,tmp,trn,crn,lrn); |
4737 } | 4737 } |
4738 code_lassign(adr,value); | 4738 code_lassign(adr,value); |
4739 free_register(lvalue); | 4739 free_register(lvalue); |
4740 free_register(adr); | 4740 free_register(adr); |
4741 } else if (l==2) { | 4741 } else if (l==2) { |
4742 int i; | 4742 int i; |
4743 int tmpvar; | 4743 int tmpvar; |
4744 // use_int(adr); | 4744 // use_int(adr); |
4745 use_longlong(value); | 4745 use_longlong(value); |
4746 lvalue = get_register(); | 4746 lvalue = get_register(); |
4747 code_register(adr,lvalue); adr = lvalue; | 4747 code_register(adr,lvalue); adr = lvalue; |
4748 tmpvar=new_lvar(SIZE_OF_LONGLONG); | 4748 tmpvar=new_lvar(SIZE_OF_LONGLONG); |
4749 code_lassign_lvar(tmpvar,value); | 4749 code_lassign_lvar(tmpvar,value); |
4750 trn = register_name(tmp = get_register()); | 4750 trn = register_name(tmp = get_register()); |
4751 | 4751 |
4752 /* make and-mask upper */ | 4752 /* make and-mask upper */ |
4753 i=bitpos; | 4753 i=bitpos; |
4754 if (i) | 4754 if (i) |
4755 oprtc(LSHIFT,(value),list2(CONST,i)); | 4755 oprtc(LSHIFT,(value),list2(CONST,i)); |
4756 if (i<0||32<=i) error(-1); | 4756 if (i<0||32<=i) error(-1); |
4757 crn = register_name(value); | 4757 crn = register_name(value); |
4758 code_ld(cload(0,0),(value),0,adr,cext_at(0,0)); | 4758 code_ld(cload(0,0),(value),0,adr,cext_at(0,0)); |
4759 lrn = register_name(value); | 4759 lrn = register_name(value); |
4760 mask = make_mask(0,31-bitpos); | 4760 mask = make_mask(0,31-bitpos); |
4761 make_mask_and_or(mask,tmp,trn,crn,lrn); | 4761 make_mask_and_or(mask,tmp,trn,crn,lrn); |
4762 printf("\t%s\t%s, 0(%s)\n",cstore(0),crn,register_name(adr)); | 4762 printf("\t%s\t%s, 0(%s)\n",cstore(0),crn,register_name(adr)); |
4763 /* | 4763 /* |
4764 <-----bitsize---------------> | 4764 <-----bitsize---------------> |
4765 hhhhhh mmmmmmmmmmmm lllllll | 4765 hhhhhh mmmmmmmmmmmm lllllll |
4766 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh | 4766 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh |
4767 |-----||-----------||------------||-------||-------| | 4767 |-----||-----------||------------||-------||-------| |
4768 <-bitpos---> | 4768 <-bitpos---> |
4769 <----------------bitsz-----------------------------> | 4769 <----------------bitsz-----------------------------> |
4770 <-----32----------> <---32------> <----32----------> | 4770 <-----32----------> <---32------> <----32----------> |
4771 */ | 4771 */ |
4772 /* store middle */ | 4772 /* store middle */ |
4773 code_lrlvar(tmpvar,value); | 4773 code_lrlvar(tmpvar,value); |
4774 i=32-bitpos; | 4774 i=32-bitpos; |
4775 if (i) | 4775 if (i) |
4776 loprtc(LRSHIFT,value,list2(CONST,i)); | 4776 loprtc(LRSHIFT,value,list2(CONST,i)); |
4777 if (i<0||64<=i) error(-1); | 4777 if (i<0||64<=i) error(-1); |
4778 printf("\t%s\t%s, 16(%s)\n",cstore(0),crn,register_name(adr)); | 4778 printf("\t%s\t%s, 16(%s)\n",cstore(0),crn,register_name(adr)); |
4779 | 4779 |
4780 /* make and-mask lower */ | 4780 /* make and-mask lower */ |
4781 code_ld(cload(0,0),(value),8,adr,cext_at(0,0)); | 4781 code_ld(cload(0,0),(value),8,adr,cext_at(0,0)); |
4782 if (i<0||64<=i) error(-1); | 4782 if (i<0||64<=i) error(-1); |
4783 mask = make_mask(bitsz-bitpos-bitsize,31); | 4783 mask = make_mask(bitsz-bitpos-bitsize,31); |
4784 make_mask_and_or(mask,tmp,trn,lrn,crn); | 4784 make_mask_and_or(mask,tmp,trn,lrn,crn); |
4785 printf("\t%s\t%s, 32(%s)\n",cstore(0),lrn,register_name(adr)); | 4785 printf("\t%s\t%s, 32(%s)\n",cstore(0),lrn,register_name(adr)); |
4786 free_lvar(tmpvar); | 4786 free_lvar(tmpvar); |
4787 free_register(adr); | 4787 free_register(adr); |
4788 #endif | 4788 #endif |
4789 } else { | 4789 } else { |
4790 // use_int(adr); | 4790 // use_int(adr); |
4791 use_int(value); | 4791 use_int(value); |
4792 lvalue = get_register(); | 4792 lvalue = get_register(); |
4793 code_ld(cload(size,sign),lvalue,0,adr,cext_at(0,0)); | 4793 code_ld(cload(size,sign),lvalue,0,adr,cext_at(0,0)); |
4794 crn = register_name(value); | 4794 crn = register_name(value); |
4795 lrn = register_name(lvalue); | 4795 lrn = register_name(lvalue); |
4796 /* shift left */ | 4796 /* shift left */ |
4797 if (bitpos) | 4797 if (bitpos) |
4798 oprtc(LSHIFT,value,list2(CONST,bitpos)); | 4798 oprtc(LSHIFT,value,list2(CONST,bitpos)); |
4799 trn = register_name(tmp = get_register()); | 4799 trn = register_name(tmp = get_register()); |
4800 /* make and-mask */ | 4800 /* make and-mask */ |
4801 mask = make_mask(32-bitpos-bitsize,31-bitpos); | 4801 mask = make_mask(32-bitpos-bitsize,31-bitpos); |
4802 make_mask_and_or(mask,tmp,trn,crn,lrn); | 4802 make_mask_and_or(mask,tmp,trn,crn,lrn); |
4803 code_assign(adr,size,value); | 4803 code_assign(adr,size,value); |
4804 free_register(lvalue); | 4804 free_register(lvalue); |
4805 } | 4805 } |
4806 if (tmp!=-1) free_register(tmp); | 4806 if (tmp!=-1) free_register(tmp); |
4807 if (use) { | 4807 if (use) { |
4808 code_bit_field(type,adr,USE_CREG); | 4808 code_bit_field(type,adr,USE_CREG); |
4809 } | 4809 } |
4816 char *trn; | 4816 char *trn; |
4817 int tmp = -1; | 4817 int tmp = -1; |
4818 int m; | 4818 int m; |
4819 // printf("## mask 0x%08x ~0x%08x\n",mask,~mask); | 4819 // printf("## mask 0x%08x ~0x%08x\n",mask,~mask); |
4820 if ((m=(~mask|c))!=-1) { | 4820 if ((m=(~mask|c))!=-1) { |
4821 if (is_stage1_const(m,0)>0) { | 4821 if (is_stage1_const(m,0)>0) { |
4822 printf("\tandi\t%s, %s, %d\n",crn,crn,m); | 4822 printf("\tandi\t%s, %s, %d\n",crn,crn,m); |
4823 } else { | 4823 } else { |
4824 trn = register_name(tmp=get_register()); | 4824 trn = register_name(tmp=get_register()); |
4825 code_const((~mask|c),tmp); | 4825 code_const((~mask|c),tmp); |
4826 /* do conjunction */ | 4826 /* do conjunction */ |
4827 printf("\tand\t%s, %s, %s\n",crn,trn,crn); | 4827 printf("\tand\t%s, %s, %s\n",crn,trn,crn); |
4828 } | 4828 } |
4829 } | 4829 } |
4830 if (tmp!=-1) { free_register(tmp); tmp=-1; } | 4830 if (tmp!=-1) { free_register(tmp); tmp=-1; } |
4831 /* make or-mask */ | 4831 /* make or-mask */ |
4832 c = mask&c; | 4832 c = mask&c; |
4833 if (c!=0) { | 4833 if (c!=0) { |
4834 /* do disjunction */ | 4834 /* do disjunction */ |
4835 if (is_stage1_const(c,0)>0) { | 4835 if (is_stage1_const(c,0)>0) { |
4836 printf("\tori\t%s, %s, %d\n",crn,crn,c); | 4836 printf("\tori\t%s, %s, %d\n",crn,crn,c); |
4837 } else { | 4837 } else { |
4838 trn = register_name(tmp=get_register()); | 4838 trn = register_name(tmp=get_register()); |
4839 code_const(c,tmp); | 4839 code_const(c,tmp); |
4840 printf("\tor\t%s, %s, %s\n",crn,trn,crn); | 4840 printf("\tor\t%s, %s, %s\n",crn,trn,crn); |
4841 } | 4841 } |
4842 } | 4842 } |
4843 if (tmp!=-1) free_register(tmp); | 4843 if (tmp!=-1) free_register(tmp); |
4844 } | 4844 } |
4845 | 4845 |
4846 extern void | 4846 extern void |
4862 if (l==1) { | 4862 if (l==1) { |
4863 #if LONGLONG_CODE | 4863 #if LONGLONG_CODE |
4864 use_int(adr); | 4864 use_int(adr); |
4865 lvalue = get_lregister(); | 4865 lvalue = get_lregister(); |
4866 lload(adr,lvalue,0); | 4866 lload(adr,lvalue,0); |
4867 crn = register_name(lvalue); | 4867 crn = register_name(lvalue); |
4868 /* shift left */ | 4868 /* shift left */ |
4869 lc = lcadr(value); | 4869 lc = lcadr(value); |
4870 lc <<= bitpos; | 4870 lc <<= bitpos; |
4871 if (bitpos+bitsize>=32) { | 4871 if (bitpos+bitsize>=32) { |
4872 /* make and-mask upper */ | 4872 /* make and-mask upper */ |
4873 mask = make_mask(64-bitpos-bitsize,bitpos>=32?63-bitpos:31); | 4873 mask = make_mask(64-bitpos-bitsize,bitpos>=32?63-bitpos:31); |
4874 make_mask_and_or_const(mask,crn,(int)(lc>>32)); | 4874 make_mask_and_or_const(mask,crn,(int)(lc>>32)); |
4875 } | 4875 } |
4876 crn = register_name(lvalue); | 4876 crn = register_name(lvalue); |
4877 if (bitpos<32) { | 4877 if (bitpos<32) { |
4878 /* make and-mask lower */ | 4878 /* make and-mask lower */ |
4879 mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); | 4879 mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); |
4880 make_mask_and_or_const(mask,crn,(int)lc); | 4880 make_mask_and_or_const(mask,crn,(int)lc); |
4881 } | 4881 } |
4882 code_lassign(adr,lvalue); | 4882 code_lassign(adr,lvalue); |
4883 free_register(adr); | 4883 free_register(adr); |
4884 free_register(lvalue); | 4884 free_register(lvalue); |
4885 } else if (l==2) { // three int container | 4885 } else if (l==2) { // three int container |
4886 char *trn; | 4886 char *trn; |
4887 /* | 4887 /* |
4888 hhhhhh mmmmmmmmmmmm lllllll | 4888 hhhhhh mmmmmmmmmmmm lllllll |
4889 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh | 4889 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh |
4890 |-----||-----------||------------||-------||-------| | 4890 |-----||-----------||------------||-------||-------| |
4891 */ | 4891 */ |
4892 use_int(adr); | 4892 use_int(adr); |
4893 crn = register_name(adr); | 4893 crn = register_name(adr); |
4894 trn = register_name(tmp = get_register()); | 4894 trn = register_name(tmp = get_register()); |
4895 /* shift right */ | 4895 /* shift right */ |
4896 lc = lcadr(value); | 4896 lc = lcadr(value); |
4897 /* make and-mask upper */ | 4897 /* make and-mask upper */ |
4898 code_ld(cload(0,0),tmp,0,adr,cext_at(0,0)); | 4898 code_ld(cload(0,0),tmp,0,adr,cext_at(0,0)); |
4899 mask = make_mask(0,31-bitpos); | 4899 mask = make_mask(0,31-bitpos); |
4900 make_mask_and_or_const(mask,trn,(int)(lc<<bitpos)); | 4900 make_mask_and_or_const(mask,trn,(int)(lc<<bitpos)); |
4901 printf("\t%s\t%s, 0(%s)\n",cstore(0),trn,crn); | 4901 printf("\t%s\t%s, 0(%s)\n",cstore(0),trn,crn); |
4902 /* store middle */ | 4902 /* store middle */ |
4903 code_const((int)(lc>>(32-bitpos)),tmp); | 4903 code_const((int)(lc>>(32-bitpos)),tmp); |
4904 printf("\t%s\t%s, 16(%s)\n",cstore(0),trn,crn); | 4904 printf("\t%s\t%s, 16(%s)\n",cstore(0),trn,crn); |
4905 /* make and-mask lower */ | 4905 /* make and-mask lower */ |
4906 code_ld(cload(0,0),tmp,8,adr,cext_at(0,0)); | 4906 code_ld(cload(0,0),tmp,8,adr,cext_at(0,0)); |
4907 mask = make_mask(bitsz-bitpos-bitsize,31); | 4907 mask = make_mask(bitsz-bitpos-bitsize,31); |
4908 make_mask_and_or_const(mask,trn,(int)(lc>>(64-bitpos))); | 4908 make_mask_and_or_const(mask,trn,(int)(lc>>(64-bitpos))); |
4909 printf("\t%s\t%s, 32(%s)\n",cstore(0),trn,crn); | 4909 printf("\t%s\t%s, 32(%s)\n",cstore(0),trn,crn); |
4910 free_register(tmp); | 4910 free_register(tmp); |
4911 #endif | 4911 #endif |
4912 } else { | 4912 } else { |
4913 use_int(adr); | 4913 use_int(adr); |
4914 lvalue = get_register(); | 4914 lvalue = get_register(); |
4915 code_ld(cload(size,sign),lvalue,0,adr,cext_at(0,0)); | 4915 code_ld(cload(size,sign),lvalue,0,adr,cext_at(0,0)); |
4916 crn = register_name(lvalue); | 4916 crn = register_name(lvalue); |
4917 /* shift left */ | 4917 /* shift left */ |
4918 c = cadr(value); | 4918 c = cadr(value); |
4919 c <<= bitpos; | 4919 c <<= bitpos; |
4920 /* make and-mask */ | 4920 /* make and-mask */ |
4921 mask = make_mask(32-bitpos-bitsize,31-bitpos); | 4921 mask = make_mask(32-bitpos-bitsize,31-bitpos); |
4922 make_mask_and_or_const(mask,crn,c); | 4922 make_mask_and_or_const(mask,crn,c); |
4923 code_assign(adr,size,lvalue); | 4923 code_assign(adr,size,lvalue); |
4924 free_register(lvalue); | 4924 free_register(lvalue); |
4925 } | 4925 } |
4926 if (use) { | 4926 if (use) { |
4927 code_bit_field(type,adr,USE_CREG); | 4927 code_bit_field(type,adr,USE_CREG); |