changeset 211:dbad3172fa14

*** empty log message ***
author kono
date Fri, 23 Apr 2004 03:27:01 +0900
parents f21651f85344
children 32f54ab63b35
files mc-code-powerpc.c
diffstat 1 files changed, 431 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-powerpc.c	Thu Apr 22 12:55:46 2004 +0900
+++ b/mc-code-powerpc.c	Fri Apr 23 03:27:01 2004 +0900
@@ -93,8 +93,8 @@
    REAL_MAX_LREGISTER];
 static int regv_h0[REAL_MAX_LREGISTER];
 static int regv_l0[REAL_MAX_LREGISTER];
-#define regv_h(i)  regv_h0[i-LREG_OFFSET]
-#define regv_l(i)  regv_l0[i-LREG_OFFSET]
+#define regv_h(i)  regv_h0[(i)-LREG_OFFSET]
+#define regv_l(i)  regv_l0[(i)-LREG_OFFSET]
 
 static int *regs  = powerpc_regs;
 
@@ -636,7 +636,8 @@
 	free_register(xreg);
 }
 
-void 
+void
+
 free_register(int i) {    /* いらなくなったレジスタを開放 */
 // printf("# free_register %d\n",i);
     regs[i]=0;
@@ -796,7 +797,8 @@
     printf("\n");
 }
 
-void 
+void
+
 gexpr_init(void)
 {
     while(reg_sp > 0) {
@@ -814,7 +816,8 @@
 }
 
 
-void 
+void
+
 emit_init(void)
 {
     free_all_register();
@@ -857,7 +860,8 @@
     return list2(LVAR,new_lvar(size_of_double));
 }
 
-void 
+void
+
 emit_push()
 {
     int new_reg;
@@ -1280,7 +1284,8 @@
 
 #define MAX_COPY_LEN 20
 
-void 
+void
+
 emit_copy(int from,int  to,int length,int offset,int value,int det)
 {
     char *frn =	register_name(from);
@@ -1816,17 +1821,8 @@
 void
 code_assign_gvar(int e2,int creg,int byte) {
     int r;
-    char *crn,*rrn;
     r = get_ptr_cache((NMTBL*)cadr(e2));
-    rrn=register_name(r);
-    crn=register_name(creg);
-    if (byte==1) {
-	printf("\tstb %s,0(%s)\n",crn,rrn);
-    } else if (byte==size_of_short) {
-	printf("\tsth %s,0(%s)\n",crn,rrn);
-    } else {
-	printf("\tstw %s,0(%s)\n",crn,rrn);
-    }
+    code_assign(r,byte,creg);
 }
 
 void
@@ -1988,7 +1984,8 @@
     return (-127<v&&v<128);
 }
 
-void 
+void
+
 oprtc(int op,int v)
 {
     char *crn = register_name(creg);
@@ -2308,7 +2305,8 @@
      */
 }
 
-void 
+void
+
 align(int t)
 {
     if (t!=CHAR) {
@@ -2596,7 +2594,8 @@
     }
 }
 
-void code_dassign_gvar(int e2,int freg,int d)
+void
+code_dassign_gvar(int e2,int freg,int d)
 { 
     int r;
     r = get_ptr_cache((NMTBL*)cadr(e2));
@@ -2604,7 +2603,8 @@
     printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(r));
 }
 
-void code_dassign_lvar(int e2,int freg,int d)
+void
+code_dassign_lvar(int e2,int freg,int d)
 { 
     lvar_intro(e2);
     if (!is_float_reg(freg)) error(-1);
@@ -2612,7 +2612,8 @@
     lvar(e2);
 }
 
-void code_dassign(int e2,int freg,int d)
+void
+code_dassign(int e2,int freg,int d)
 { 
     if (!is_float_reg(freg)) error(-1);
     printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(e2));
@@ -2650,7 +2651,8 @@
     return *j;
 }
 
-void 
+void
+
 code_dconst(int e2,int freg,int d)
 { 
     int lb;
@@ -2697,14 +2699,16 @@
 }
 
 
-void code_dneg(int freg,int d)
+void
+code_dneg(int freg,int d)
 { 
     char *frn = fregister_name(freg);
     if (is_int_reg(freg)) error(-1);
     printf("\tfneg %s,%s\n",frn,frn);
 }
 
-void code_d2i(int freg0)
+void
+code_d2i(int freg0)
 { 
     char *frn;
     char *crn;
@@ -2752,7 +2756,8 @@
 0
 };
 
-void code_i2d(int creg0)
+void
+code_i2d(int creg0)
 { 
     i2d_lib_used = 1;
     clear_ptr_cache();
@@ -2798,7 +2803,8 @@
 0
 };
 
-void code_d2u(int freg0)
+void
+code_d2u(int freg0)
 { 
     code_save_stacks();
     clear_ptr_cache();
@@ -2835,7 +2841,8 @@
 0
 };
 
-void code_u2d(int creg0)
+void
+code_u2d(int creg0)
 { 
     code_save_stacks();
     clear_ptr_cache();
@@ -2845,14 +2852,21 @@
     set_freg(FREG_FREGISTER,0);
 }
 
-void code_d2f(int freg) { }
-void code_f2d(int freg) { }
-void code_f2i(int freg) { code_d2i(freg); }
-void code_f2u(int freg) { code_d2u(freg); }
-void code_i2f(int creg) { code_i2d(creg); }
-void code_u2f(int creg) { code_u2d(creg); }
-
-void code_drgvar(int e2,int d,int freg)
+void
+code_d2f(int freg) { }
+void
+code_f2d(int freg) { }
+void
+code_f2i(int freg) { code_d2i(freg); }
+void
+code_f2u(int freg) { code_d2u(freg); }
+void
+code_i2f(int creg) { code_i2d(creg); }
+void
+code_u2f(int creg) { code_u2d(creg); }
+
+void
+code_drgvar(int e2,int d,int freg)
 { 
     int r;
     r = get_ptr_cache((NMTBL*)cadr(e2));
@@ -2860,13 +2874,15 @@
 }
 
 
-void code_drlvar(int e2,int d,int freg)
+void
+code_drlvar(int e2,int d,int freg)
 { 
     lvar_intro(e2);
     printf("\t%s %s,",fload(d),fregister_name(freg)); lvar(e2);
 }
 
-void code_cmp_drgvar(int e2,int d)
+void
+code_cmp_drgvar(int e2,int d)
 { 
     int r;
     char *frn=fregister_name(freg);
@@ -2878,7 +2894,8 @@
     free_register(g);
 }
 
-void code_cmp_drlvar(int e2,int d)
+void
+code_cmp_drlvar(int e2,int d)
 { 
     char *frn=fregister_name(freg);
     int g=get_dregister(d);
@@ -2890,7 +2907,8 @@
     free_register(g);
 }
 
-void dtosop(int op,int e1)
+void
+dtosop(int op,int e1)
 { 
     char *opn="";
     char *frn=fregister_name(freg);
@@ -3045,12 +3063,14 @@
     return xreg;
 }
 
-void emit_dpop_free(int e1,int d)
+void
+emit_dpop_free(int e1,int d)
 { 
     free_register(e1);
 }
 
-void emit_dpush(int d)
+void
+emit_dpush(int d)
 { 
     int new_reg;
     if (freg_sp>MAX_MAX) error(-1);
@@ -3066,7 +3086,7 @@
 
 /* 64bit int part */
 
-static
+static void
 cond(char *s,int l1)
 {
     printf("\tb%s cr0,L_%d\n",s,l1);
@@ -3082,8 +3102,8 @@
     g_expr(e2);
     e3 = emit_lpop();
 
-    creg = regv_h[creg_save = creg];
-    tosop(CMP,regv_h[e3]);
+    creg = regv_h(creg_save = creg);
+    tosop(CMP,regv_h(e3));
     switch(op) {
     case LOP+GT:
     	cond(code_gt(1),l1); break;
@@ -3104,8 +3124,8 @@
     default:
 	error(-1);
     }
-    creg = regv_l[creg_save];
-    tosop(CMP,regv_l[e3]);
+    creg = regv_l(creg_save);
+    tosop(CMP,regv_l(e3));
     switch(op) {
     case LOP+GT:
     	cond(code_gt(1),l1); break;
@@ -3129,12 +3149,14 @@
     emit_lpop_free(e3);
 }
 
-int lpop_register()
+int
+lpop_register()
 {
     return lreg_stack[--lreg_sp];
 }
 
-int emit_lpop()
+int
+emit_lpop()
 {
     int xreg,reg;
     xreg=lpop_register();
@@ -3147,44 +3169,78 @@
     return xreg;
 }
 
-void code_lregister(int e2,int reg)
+void
+code_lregister(int e2,int reg)
 {
-
-}
-
-void code_cmp_lregister(int reg)
-{
-
+    if (creg!=e2) {
+	printf("\tmr %s,%s\n",lregister_name_low(creg),
+		lregister_name_low(e2));
+	printf("\tmr %s,%s\n",lregister_name_high(creg),
+		lregister_name_high(e2));
+    }
 }
 
-void code_cmp_lrgvar(int e1,int e2)
+void
+code_cmp_lregister(int reg)
 {
-
+    printf("\tor %s,%s,%s\n",
+		lregister_name_low(reg),
+		lregister_name_low(reg),
+		lregister_name_high(reg));
+    printf("\tcmpwi cr0,%s,0\n",lregister_name_low(reg));
 }
 
-void code_cmp_lrlvar(int e1,int e2)
+void
+code_cmp_lrgvar(int e1,int creg)
 {
-
+    code_lrgvar(e1,creg);
+    code_cmp_lregister(creg);
+}
+
+void
+code_cmp_lrlvar(int e1,int creg)
+{
+    code_lrlvar(e1,creg);
+    code_cmp_lregister(creg);
 }
 
-void code_lassign(int e1,int e2)
+void
+code_lassign(int e2,int creg)
 {
-
+    char *drn = register_name(e2);
+    char *crn_h = lregister_name_high(creg);
+    char *crn_l = lregister_name_low(creg);
+
+    printf("\tstw %s,0(%s)\n",crn_h,drn);
+    printf("\tstw %s,%d(%s)\n",crn_l,size_of_int,drn);
 }
 
-void code_lassign_gvar(int e1,int e2)
+void
+code_lassign_gvar(int e2,int creg)
 {
-
+    int r;
+    if (!is_longlong_reg(creg)) error(-1);
+    r = get_ptr_cache((NMTBL*)cadr(e2));
+    code_lassign(r,creg);
 }
 
-void code_lassign_lvar(int e1,int e2)
+void
+code_lassign_lvar(int e2,int creg)
 {
-
+    char *crn_h = lregister_name_high(creg);
+    char *crn_l = lregister_name_low(creg);
+    lvar_intro(e2);
+    printf("\tstw %s,",crn_h);lvar(e2);
+    printf("\tstw %s,",crn_l);lvar(e2+size_of_int);
 }
 
-void code_lassign_lregister(int e2,int reg)
+void
+code_lassign_lregister(int e2,int reg)
 {
-
+    if (e2!=creg) {
+        printf("\tmr %s,%s\n",lregister_name_high(e2),lregister_name_high(creg));
+        printf("\tmr %s,%s\n",lregister_name_low(e2),lregister_name_low(creg));
+    }
 }
 
 static long long ll0 = 1LL;
@@ -3203,128 +3259,308 @@
     return (i[1] == 1)?j[0]:j[1];
 }
 
-void code_lconst(int e1,int e2)
+void
+code_lconst(int e1,int creg)
+{
+    code_const(code_l1(lcadr(e1)),regv_l(creg));
+    code_const(code_l2(lcadr(e1)),regv_h(creg));
+}
+
+void
+code_lneg(int creg)
 {
-
+    printf("\tsubfic %s,%s,0\n",
+	lregister_name_low(creg),lregister_name_low(creg));
+    printf("\tsubfze %s,%s,0\n",
+	lregister_name_high(creg),lregister_name_high(creg));
 }
 
-void code_lneg(int e1,int e2)
+void
+code_lrgvar(int e1,int e2)
+{
+    int r;
+    char *crn_h = lregister_name_high(creg);
+    char *crn_l = lregister_name_low(creg);
+    if (!is_longlong_reg(creg)) error(-1);
+    r = get_ptr_cache((NMTBL*)cadr(e1));
+    printf("\tlwz %s,0(%s)\n",crn_h,register_name(r));
+    printf("\tlwz %s,%d(%s)\n",crn_l,size_of_int,register_name(r));
+}
+
+void
+code_lrlvar(int e1,int creg)
 {
-
+    char *crn_h = lregister_name_high(creg);
+    char *crn_l = lregister_name_low(creg);
+    lvar_intro(e1);
+    printf("\tlwz %s,",crn_h); lvar(e1);
+    printf("\tlwz %s,",crn_l); lvar(e1+size_of_int);
 }
 
-void code_lrgvar(int e1,int e2)
-{
-
+static int asld_lib_used=0;
+static char *asld_lib[] = {
+".data",
+/* ".literal8", */
+"        .align 3",
+"__u2dLC1:",
+"        .long   1127219200",
+"        .long   0",
+".text",
+"        .align 2",
+"u2d_:",
+"        mflr r0",
+"        bcl 20,31,__u2dL2$pb",
+"__u2dL2$pb:",
+"        mflr r10",
+"        mtlr r0",
+"        stw r3,-28(r30)",
+"        lis r0,0x4330",
+"        stw r0,-32(r30)",
+"        lfd f0,-32(r30)",
+"        addis r9,r10,ha16(__u2dLC1-__u2dL2$pb)",
+"        lfd f1,lo16(__u2dLC1-__u2dL2$pb)(r9)",
+"        fsub f1,f0,f1",
+"        blr",
+0
+};
+
+void
+code_asld_lib(int creg0)
+{ 
+    code_save_stacks();
+    clear_ptr_cache();
+    asld_lib_used = 1;
+    printf("\tbl asld_\n");
 }
 
-void code_lrlvar(int e1,int e2)
-{
-
-}
-
-void ltosop(int e1,int e2)
+void
+ltosop(int op,int oreg)
 {
-
+    int dx;
+    char *orn_h,*crn_h,*drn_h;
+    char *orn_l,*crn_l,*drn_l;
+
+    if(oreg==-1) {
+	error(-1);
+    } else if (oreg<= -REG_LVAR_OFFSET) {
+	dx = get_lregister(); if (dx<0) error(-1);
+        code_rlvar(oreg+REG_LVAR_OFFSET,dx);
+	oreg = dx;
+    }
+
+    switch(op) {
+    case LLSHIFT:
+    case LULSHIFT:
+	code_asld_lib(oreg);
+	return;
+    case LRSHIFT:
+	shift("sraw",oreg);
+	return;
+    case LURSHIFT:
+	shift("srw",oreg);
+	return;
+    }
+    orn_h = lregister_name_high(oreg);
+    orn_l = lregister_name_low(oreg);
+    crn_h = lregister_name_high(creg);
+    crn_l = lregister_name_low(creg);
+    switch(op) {
+    case ADD:
+	printf("\taddc %s,%s,%s\n",crn_l,crn_l,orn_l);
+	printf("\tadde %s,%s,%s\n",crn_h,crn_h,orn_h);
+	break;
+    case SUB:
+	printf("\tsubfc %s,%s,%s\n",crn_l,crn_l,orn_l);
+	printf("\tsubfe %s,%s,%s\n",crn_h,crn_h,orn_h);
+	break;
+    case LCMP:
+	error(-1);
+	break;
+    case BAND: 
+	printf("\tand %s,%s,%s\n",crn_l,crn_l,orn_l);
+	printf("\tand %s,%s,%s\n",crn_h,crn_h,orn_h);
+	break;
+    case EOR: 
+	printf("\txor %s,%s,%s\n",crn_l,crn_l,orn_l);
+	printf("\txor %s,%s,%s\n",crn_h,crn_h,orn_h);
+	break;
+    case BOR:
+	printf("\tor %s,%s,%s\n",crn_l,crn_l,orn_l);
+	printf("\tor %s,%s,%s\n",crn_h,crn_h,orn_h);
+	break;
+    case MUL:
+    case UMUL:
+	dx=get_lregister();
+	drn_l = lregister_name_low(dx);
+	drn_h = lregister_name_high(dx);
+        /*
+            drn_l = l32( crn_l * orn_l);
+            drn_h = h32( crn_l * orn_l);
+            orn_l = l32( crn_h * orn_l);
+	    drn_h = drn_h + orn_l;
+            crn_l = l32( crn_l * orn_h);
+	    crn_h = drn_h + crn_l;
+	    crn_l = drn_l;
+        */
+	printf("\tmullw %s,%s,%s\n",drn_l,crn_l,orn_l);
+	printf("\tmulhwu %s,%s,%s\n",drn_h,crn_l,orn_l);
+	printf("\tmullw %s,%s,%s\n",orn_l,crn_h,orn_l);
+	printf("\tadd %s,%s,%s\n",drn_h,drn_h,orn_l);
+	printf("\tmullw %s,%s,%s\n",crn_l,orn_h,crn_l);
+	printf("\tadd %s,%s,%s\n",crn_l,drn_h,crn_h);
+	printf("\tmr %s,%s\n",crn_l,drn_l);
+	break;
+    case DIV:
+	printf("\tdivw %s,%s,%s\n",crn,crn,orn);
+	break;
+    case UDIV:
+	printf("\tdivwu %s,%s,%s\n",crn,crn,orn);
+	break;
+    case MOD:
+	dx=get_register();
+	drn = register_name(dx);
+	printf("\tdivw %s,%s,%s\n",drn,crn,orn);
+	printf("\tmullw %s,%s,%s\n",drn,drn,orn);
+	printf("\tsubf %s,%s,%s\n",crn,drn,crn);
+	free_register(dx);
+	break;
+    case UMOD:
+	dx=get_register();
+	drn = register_name(dx);
+	printf("\tdivwu %s,%s,%s\n",drn,crn,orn);
+	printf("\tmullw %s,%s,%s\n",drn,drn,orn);
+	printf("\tsubf %s,%s,%s\n",crn,drn,crn);
+	free_register(dx);
+	break;
+    default:
+	error(-1);
+    }
+    if(oreg!=creg) free_register(oreg);
 }
 
-void emit_lpop_free(int e1)
+void
+emit_lpop_free(int xreg)
 {
-
+    if (xreg>=0)
+        free_register(xreg);
 }
 
-void emit_lpush()
+void
+emit_lpush()
+{
+    int new_reg;
+    if (!is_longlong(creg)) error(-1);
+    if (lreg_sp>MAX_MAX) error(-1);
+    new_reg = get_lregister();
+    lreg_stack[lreg_sp++] = creg;     /* push するかわりにレジスタを使う */
+    lreg = creg = new_reg;
+}
+
+void
+code_i2ll(int creg)
 {
 
 }
 
-void code_i2ll(int creg)
+void
+code_i2ull(int creg)
 {
 
 }
 
-void code_i2ull(int creg)
+void
+code_u2ll(int creg)
 {
 
 }
 
-void code_u2ll(int creg)
+void
+code_u2ull(int creg)
 {
 
 }
 
-void code_u2ull(int creg)
-{
-
-}
-
-void code_ll2i(int creg)
+void
+code_ll2i(int creg)
 {
 
 }
 
-void code_ll2u(int creg)
+void
+code_ll2u(int creg)
 {
 
 }
 
-void code_ull2i(int creg)
+void
+code_ull2i(int creg)
 {
 
 }
 
-void code_ull2u(int creg)
+void
+code_ull2u(int creg)
 {
 
 }
 
 #if FLOAT_CODE
-void code_d2ll(int creg)
+void
+code_d2ll(int creg)
 {
 
 }
 
-void code_d2ull(int creg)
+void
+code_d2ull(int creg)
 {
 
 }
 
-void code_f2ll(int creg)
+void
+code_f2ll(int creg)
 {
 
 }
 
-void code_f2ull(int creg)
+void
+code_f2ull(int creg)
 {
 
 }
 
-void code_ll2d(int creg)
+void
+code_ll2d(int creg)
 {
 
 }
 
-void code_ll2f(int creg)
+void
+code_ll2f(int creg)
 {
 
 }
 
-void code_ull2d(int creg)
+void
+code_ull2d(int creg)
 {
 
 }
 
-void code_ull2f(int creg)
+void
+code_ull2f(int creg)
 {
 
 }
 
-void code_ull2ll(int creg)
+void
+code_ull2ll(int creg)
 {
 
 }
 
-void code_ull2ull(int creg)
+void
+code_ull2ull(int creg)
 {
 
 }
@@ -3332,19 +3568,101 @@
 #endif
 
 
-void code_lpreinc(int e1,int e2,int reg)
+void
+code_lpreinc(int e1,int e2,int reg)
 {
-
+    char *xrn,*drn_h,*drn_l;
+    int i,dreg;
+    int dir=caddr(e1);
+    if (car(e2)==LREGISTER) {
+        printf("\taddci %s,%s,%d\n", 
+                lregister_name_low(cadr(e2)),lregister_name_low(cadr(e2)), dir);
+        printf("\taddei %s,%s,0\n", 
+                lregister_name_high(cadr(e2)),lregister_name_high(cadr(e2)));
+        if (cadr(reg)!=cadr(e2)) {
+            printf("\tmr %s,%s\n",lregister_name_low(cadr(reg)),
+		lregister_name_low(cadr(e2)));
+            printf("\tmr %s,%s\n",lregister_name_high(cadr(reg)),
+		lregister_name_high(cadr(e2)));
+	}
+        return;
+    } 
+    g_expr(e2);
+    xrn = register_name(creg);
+    dreg=get_lregister(); if (!dreg) error(-1);
+    drn_h = lregister_name_high(dreg);
+    drn_l = lregister_name_low(dreg);
+    printf("\tlzw %s,%d(%s)\n",drn_l,size_of_int,xrn);
+    printf("\tlzw %s,0(%s)\n",drn_h,xrn);
+    printf("\taddci %s,%s,%d\n",drn_l,drn_l,dir);
+    printf("\taddei %s,%s,0\n",drn_h,drn_h,dir);
+    printf("\tstw %s,%d(%s)\n",drn_l,size_of_int,xrn);
+    printf("\tstw %s,0(%s)\n",drn_h,xrn);
+    set_lreg(dreg);
 }
 
-void code_lpostinc(int e1,int e2,int reg)
+void
+code_lpostinc(int e1,int e2,int reg)
 {
-
+    char *xrn,*drn_h,*drn_l;
+    char *nrn_h,*nrn_l;
+    int i,dreg,nreg;
+    int dir=caddr(e1);
+    if (car(e2)==LREGISTER) {
+	printf("\tmr %s,%s\n",lregister_name_low(cadr(reg)),
+	    lregister_name_low(cadr(e2)));
+	printf("\tmr %s,%s\n",lregister_name_high(cadr(reg)),
+	    lregister_name_high(cadr(e2)));
+        printf("\taddci %s,%s,%d\n", 
+                lregister_name_low(cadr(e2)),lregister_name_low(cadr(e2)), dir);
+        printf("\taddei %s,%s,0\n", 
+                lregister_name_high(cadr(e2)),lregister_name_high(cadr(e2)));
+        return;
+    } 
+    g_expr(e2);
+    xrn = register_name(creg);
+    dreg=get_lregister(); if (!dreg) error(-1);
+    nreg=get_lregister(); if (!dreg) error(-1);
+    drn_h = lregister_name_high(dreg);
+    drn_l = lregister_name_low(dreg);
+    nrn_h = lregister_name_high(nreg);
+    nrn_l = lregister_name_low(nreg);
+    printf("\tlzw %s,%d(%s)\n",drn_l,size_of_int,xrn);
+    printf("\tlzw %s,0(%s)\n",drn_h,xrn);
+    printf("\taddci %s,%s,%d\n",nrn_l,drn_l,dir);
+    printf("\taddei %s,%s,0\n",nrn_h,drn_h,dir);
+    printf("\tstw %s,%d(%s)\n",nrn_l,size_of_int,xrn);
+    printf("\tstw %s,0(%s)\n",nrn_h,xrn);
+    free_register(nreg);
+    set_lreg(dreg);
 }
 
-void code_lassop(int op)
+void
+code_lassop(int op)
 {
-
+    int xreg;
+    int edx,edx0=-1;
+    xreg = emit_lpop(0);       /* pop e3 value */
+    if (!is_int_reg(creg)) error(-1);
+    edx = creg;
+    creg = use_longlong(creg);
+    if (regv_l(creg)==edx || regv_h(creg)==edx) {
+	edx0 = get_register(); if(!edx0) error(-1);
+	printf("# lassop\n\tmr %s,%s\n",register_name(edx0),register_name(edx));
+	edx = edx0;
+    }
+    use_reg(edx);
+    printf("\tlwz %s,0(%s)\n",lregister_name_high(creg),
+	register_name(edx));
+    printf("\tlwz %s,%d(%s)\n",lregister_name_low(creg),
+	size_of_int,register_name(edx));
+    ltosop(op,xreg);
+    printf("\tstw %s,0(%s)\n",lregister_name_high(creg),
+	register_name(edx));
+    printf("\tstw %s,%d(%s)\n",lregister_name_low(creg),
+	size_of_int,register_name(edx));
+    free_register(edx);
+    emit_lpop_free(xreg);
 }