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&&reg == creg) { 1588 if (creg&&reg == 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,&reg_arg,&freg_arg); 1752 increment_function_arg(e3,&nargs,&reg_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,&reg_arg,&freg_arg), 1797 increment_function_arg(e3,&nargs,&reg_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,&reg_arg,&freg_arg), 1815 increment_function_arg(e3,&nargs,&reg_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&&reg!=RET_REGISTER) { 4041 if (reg!=USE_CREG&&reg!=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&&reg!=RET_REGISTER) { 4051 if (reg!=USE_CREG&&reg!=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&&reg!=RET_REGISTER) { 4061 if (reg!=USE_CREG&&reg!=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&&reg!=RET_REGISTER) { 4071 if (reg!=USE_CREG&&reg!=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&&reg!=RET_REGISTER) 4082 if (reg!=USE_CREG&&reg!=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&&reg!=RET_REGISTER) 4093 if (reg!=USE_CREG&&reg!=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);