Mercurial > hg > CbC > old > device
changeset 282:d61cf7a9b469
first jmp in MIPS
author | kono |
---|---|
date | Mon, 24 May 2004 07:37:42 +0900 |
parents | 1d60bbd8d3f8 |
children | 230a3b98b843 |
files | Changes mc-code-mips.c stdio.h |
diffstat | 3 files changed, 117 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sun May 23 17:01:10 2004 +0900 +++ b/Changes Mon May 24 07:37:42 2004 +0900 @@ -4445,3 +4445,87 @@ long long の比較は int の比較から作る汎用ルーチンを作った方が 良くない? + +つうか、まったく間違ってました。 + +Sun May 23 17:10:59 JST 2004 + +やっとMIPSが仕上ったよ。まだ、code jump は、できてないけど。 + +そもそも external jumpができるかどうか調べてないな。 + +slt $r1,$r2,12 みたいなコードも出したいが... + +parallel_rassign って target=soruce で無限ループしない? + +Sun May 23 21:21:22 JST 2004 + +やっぱり、boolean の扱いがなぁ。jmpでない方が良いよね。 + +Mon May 24 07:11:57 JST 2004 + +関数呼び出しの引数は、やっぱり$spオフセットで積むべきでしょう。 +でないと、$fp!=$sp の時におかしくなる。($s8=$fp) + +code から大域変数が読めない。 + +0x401170 <main1>: lui $gp,0xfc0 +0x401174 <main1+4>: addiu $gp,$gp,28352 +0x401178 <main1+8>: addu $gp,$gp,$t9 +0x40117c <main1+12>: addiu $sp,$sp,-144 +0x401180 <main1+16>: sw $gp,16($sp) +0x401184 <main1+20>: sw $ra,136($sp) +0x401188 <main1+24>: b 0x401234 <main1+196> +0x40118c <main1+28>: sw $s8,132($sp) +0x401190 <main1+32>: move $s8,$sp + +0x400aa0 <carg1>: lui $gp,0xfc0 +0x400aa4 <carg1+4>: addiu $gp,$gp,30096 +0x400aa8 <carg1+8>: addu $gp,$gp,$t9 +0x400aac <carg1+12>: addiu $sp,$sp,-144 +0x400ab0 <carg1+16>: sw $gp,32($sp) +0x400ab4 <carg1+20>: move $s8,$sp + +ですか。$t9 ってなんだろう? + +0x401290 <main+48>: lw $t9,-32744($gp) +0x401294 <main+52>: addiu $t9,$t9,4464 +0x401298 <main+56>: jalr $t9 +0x40129c <main+60>: nop +0x4012a0 <main+64>: lw $gp,16($s8) + +これか。ってことは、恐れていた通り、 + printf("\tj %s\n",s); +ではだめなのね。 + +$t8 は、$25 ってことは、$t9 は$26? jmp先みたいだね。 $jp? +cpload $25 の$25 じゃないの? じゃぁ、 + jrn = register_name(cadr(jmp)); + printf("\tmove $25,%s\n",jrn); + printf("\tjal\t$31,$25\n"); +すればいいのかな? + +.ent しないっていう手もあるけど... 外から入って来た時に +どうする? (そもそも、code って、外から呼び出せるの?) + + printf("\tla $25,%s\n",s); + printf("\tj\t$25\n"); + +でいいみたいだね。 + 1,9d0 + < arg1: 0 1 2 3 4 : 1 1 + < arg1: 1 2 3 4 0 : 1 1 + < args: 1 2 3 4 0 : 1 1 + < 321=0 + < args3: 11 22 33 44 55 : 1 2 3 4 + < args4: 11 22 33 44 55 : 2 3 4 1 + < args5: 66 77 88 99 10 : 3 4 1 2 + < args6: 66 77 88 99 10 : 3 4 1 2 + < args3: 66 77 88 99 10 : 3 4 1 2 + make: [check-code] Error 1 (ignored) + +pstwo1+kono ./a.out + arg1: 0 1 2 3 4 : 0 0 + arg1: 1 2 3 4 0 : 0 0 + args: 0 263785888 4200109 2712942 0 : 0 0 + Segmentation fault +ま、いろいろあるね。
--- a/mc-code-mips.c Sun May 23 17:01:10 2004 +0900 +++ b/mc-code-mips.c Mon May 24 07:37:42 2004 +0900 @@ -319,7 +319,7 @@ <-------r1_offset------------------------------> <------------lvar_offset-------> <-arg_offset-> - r+ +-----------+----+---------------+----------+--- ----------+----+ + r+ +-----------+----+---------------+----------+-------------+----+ callee arg xxx register save local caller arg xxx ($r31)($fp) reg_save disp max_func_args*SIZE_OF_INT lvar>0 lvar<0 lvar>0x1000 0000 @@ -402,7 +402,7 @@ if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ printf("%d($fp)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); } else - printf("%d($fp)\n",CODE_LVAR(l-ARG_LVAR_OFFSET)); + printf("%d($fp)\n",CODE_LVAR(l)); } else if (l<0) { /* local variable */ printf("%d+$L_%d($fp)\n",FUNC_LVAR(l),lvar_offset_label); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ @@ -2183,7 +2183,8 @@ // jump to continuation means use all register variable max_reg_var = REG_VAR_BASE-REG_VAR_MIN; max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; - printf("\tj %s\n",s); + printf("\tla $25,%s\n",s); + printf("\tj\t$25\n"); } @@ -2520,12 +2521,25 @@ if(ox!=-1) free_register(ox); } +static int +ilog(int i) +{ + int j,k; + for(k=1,j=0;j<8;j++,k+=k) { + if (i==k) + return j; + } + return 0; +} + int code_const_op_p(int op,int v) { if (car(v)!=CONST) return 0; + v = cadr(v); + if (op==MUL||op==UMUL) return ilog(v) ; + if (op==DIV||op==UDIV) return ilog(v) ; if (!(op==LSHIFT|| op==ULSHIFT|| op==RSHIFT|| op==URSHIFT|| op==ADD|| op==SUB|| op==CMP|| op==BOR)) return 0; - v = cadr(v); return (-32766<v&&v<32767); } @@ -2561,6 +2575,15 @@ case BOR: printf("\tori %s,%s,%d\n",crn,crn,v); break; + case MUL: case UMUL: + printf("\tsll %s,%s,%d\n",crn,crn,ilog(v)); + break; + case UDIV: + printf("\tsrl %s,%s,%d\n",crn,crn,ilog(v)); + break; + case DIV: + printf("\tsra %s,%s,%d\n",crn,crn,ilog(v)); + break; default: error(-1); } @@ -2656,7 +2679,7 @@ char *eq = "eq"; char *ne = "ne"; int t; -printf("# pcond %d cond %d\n",op,cond); +// printf("# pcond %d cond %d\n",op,cond); switch(op+(!cond)*BNOT) { case GT: case LE+BNOT: t=r1;r1=r0;r0=t;
--- a/stdio.h Sun May 23 17:01:10 2004 +0900 +++ b/stdio.h Mon May 24 07:37:42 2004 +0900 @@ -1,4 +1,4 @@ -#ifndef __micro_c__aaa +#ifndef __micro_c__ #include "/usr/include/stdio.h" long long strtoll(const char *, char **, int); #else @@ -47,7 +47,7 @@ #define EOF (-1) #define NULL 0 -typedef int size_t; +typedef int SIZE_T_; typedef /*long*/ int fpos_t; typedef void *__gnuc_va_list; @@ -65,7 +65,7 @@ int fpurge(); int fputc(int, FILE *); int fputs(const char *, FILE *); -size_t fread(void *, size_t, size_t, FILE *); +SIZE_T_ fread(void *, size_t, size_t, FILE *); int fscanf(FILE *, const char *, ...); /* int fseek(FILE *, long int, int); */ @@ -74,7 +74,7 @@ long ftell(FILE *); int ftrylockfile(); void funlockfile(); -size_t fwrite(const void *, size_t, size_t, FILE *); +SIZE_T_ fwrite(const void *, size_t, size_t, FILE *); int getc(FILE *); int getc_unlocked(); int getchar(void); @@ -96,7 +96,7 @@ void setbuf(FILE *, char *); void setbuffer(); int setlinebuf(); -int setvbuf(FILE *, char *, int, size_t); +int setvbuf(FILE *, char *, int, SIZE_T_); int snprintf(); int sprintf(char *, const char *, ...); int sscanf(const char *, const char *, ...);