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 *, ...);