diff --git a/BuildName.txt b/BuildName.txt
index df249f93cddf80b1f063775a98de6ecdbe8f2337..5ff12ff9f271f4aea019d489930009f0961964e8 100644
--- a/BuildName.txt
+++ b/BuildName.txt
@@ -1 +1 @@
-49.x86fre.master.230807-2311
+50.x86fre.master.230810-1506
diff --git a/__blddate__ b/__blddate__
index 949c401a9c6a1bfe82a1e9810b85c4b2b0b70814..b6a66803d3589ddc9478decbf97910ea0d61c01c 100644
--- a/__blddate__
+++ b/__blddate__
@@ -1 +1 @@
-BUILDDATE=230807-2311
\ No newline at end of file
+BUILDDATE=230810-1506
\ No newline at end of file
diff --git a/__bldnum__ b/__bldnum__
index b77ef58f621d6df590042c9c8c59d987da4e211b..fffc8bd0df72b6751881ea0bbc978e561935a6dc 100644
--- a/__bldnum__
+++ b/__bldnum__
@@ -1 +1 @@
-BUILDNUMBER=49
+BUILDNUMBER=50
diff --git a/back/ARMv7/instsel.c b/back/ARMv7/instsel.c
index d5a8aa2de7b57cc5c6f0ae09499dde28f8590fc9..7a2a3530de45285629e4eb4033cb26bad8730613 100644
--- a/back/ARMv7/instsel.c
+++ b/back/ARMv7/instsel.c
@@ -48,12 +48,6 @@ char *opCodeTab[] = {
     "mov",          /* 数据传送指令     mov */
     "ldr",          /* 数据传送指令     ldr */
     "str",          /* 数据传送指令     str */
-    "moveq",        /* 数据传送指令     moveq */
-    "movne",        /* 数据传送指令     movne */
-    "movle",        /* 数据传送指令     movle */
-    "movgt",        /* 数据传送指令     movgt */
-    "movlt",        /* 数据传送指令     movlt */
-    "movge",        /* 数据传送指令     movge */
     "vmrs",         /* 数据传送指令     vmrs */
     "vmov",         /* 数据传送指令     vmov */
     "vldr.32",      /* 数据传送指令     vldr.32 */
@@ -86,12 +80,6 @@ char *opCodeTab[] = {
     "vcmpe.f32",    /* 浮点比较指令     vcmpe.f32 */
                     /* 跳转指令 */
     "bx",           /* 跳转指令     间接跳转 */
-    "beq",          /* 跳转指令     == */
-    "bne",          /* 跳转指令     != */
-    "blt",          /* 跳转指令     < */
-    "ble",          /* 跳转指令     <= */
-    "bgt",          /* 跳转指令     > */
-    "bge",          /* 跳转指令     >= */
     "b",            /* 跳转指令     goto */
     "bl",           /* 跳转指令     bl */
                     /* 函数调用相关指令 */
@@ -107,6 +95,27 @@ char *opCodeTab[] = {
     "@DBG: ",       /* 伪指令     调试 */
 };
 
+// https://developer.arm.com/documentation/dui0801/l/Condition-Codes/Condition-code-suffixes?lang=en
+char *condCodeTab[] = {
+    "al",       /* Always (this is the default) */
+    "eq",       /* Equal */
+    "ne",       /* Not equal */
+    "cs",       /* Carry set (identical to HS) */
+    "hs",       /* Unsigned higher or same (identical to CS) */
+    "cc",       /* Carry clear (identical to LO) */
+    "lo",       /* Unsigned lower (identical to CC) */
+    "mi",       /* Minus or negative result */
+    "pl",       /* Positive or zero result */
+    "vs",       /* Overflow */
+    "vc",       /* No overflow */
+    "hi",       /* Unsigned higher */
+    "ls",       /* Unsigned lower or same */
+    "ge",       /* Signed greater than or equal */
+    "lt",       /* Signed less than */
+    "gt",       /* Signed greater than */
+    "le",       /* Signed less than or equal */
+};
+
 static int asm_entry(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
 static int asm_addexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
 static int asm_assign(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
@@ -188,7 +197,7 @@ static void DestroyUDData(void* p, void* T) ;
 static PVIRTREGINFO emitstorearg (PLLI instructions, int dest, PVIRTREGINFO src);
 
 static PVIRTREGINFO expand_mult(PVIRTREGINFO op0, void* op1, int IsImm, PLLI instructions, PDYNAMIC_ARRAY virtregs);
-static PVIRTREGINFO expand_binop(PVIRTREGINFO op0, void* op1, int IsImm, OPCODE op, PLLI instructions, PDYNAMIC_ARRAY virtregs);
+static PVIRTREGINFO expand_binop(PVIRTREGINFO op0, void* op1, int IsImm, OPCODE op, int suffix, condition_code cond, PLLI instructions, PDYNAMIC_ARRAY virtregs);
 static PVIRTREGINFO expand_divmod (PVIRTREGINFO op0, void* op1, int IsImm, int mod_flag, PLLI instructions, PDYNAMIC_ARRAY virtregs);
 
 /* ARCompact stack frames look like:
@@ -802,6 +811,8 @@ static int asm_addexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMT
     if (ret2 > 2 && ret > 2)
         { // 两个常数相加、减、乘、除、取模,不可能出现。
         internal_error(NULL, "Fatal error on line %u of %s.", __LINE__, __FILE__);
+        PrintInstruction(stdout, currentinstruction, 0, 1);
+        fprintf(stdout, " in block %lu\n", bb_GetIdent(currentinstruction->bb));
         goto cleanup;
         }
 
@@ -863,7 +874,7 @@ static int asm_addexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMT
     switch (iop)
     {
     case IRINST_OP_PLUS:
-        reg3 = expand_binop(reg1, ret2 > 2 ? (void*)&TheValue2.integer_val : (void*)iarg2, ret2 > 2, type == Float ? opvaddf32 : opadd, instructions, &pMyData->virtreg);
+        reg3 = expand_binop(reg1, ret2 > 2 ? (void*)&TheValue2.integer_val : (void*)iarg2, ret2 > 2, type == Float ? opvaddf32 : opadd, 0, CONDITION_AL, instructions, &pMyData->virtreg);
         if (!reg3)
             {
             goto cleanup;
@@ -871,7 +882,7 @@ static int asm_addexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMT
         break;
 
     case IRINST_OP_MINUS:
-        reg3 = expand_binop(reg1, ret2 > 2 ? (void*)&TheValue2.integer_val : (void*)iarg2, ret2 > 2, type == Float ? opvsubf32 : opsub, instructions, &pMyData->virtreg);
+        reg3 = expand_binop(reg1, ret2 > 2 ? (void*)&TheValue2.integer_val : (void*)iarg2, ret2 > 2, type == Float ? opvsubf32 : opsub, 0, CONDITION_AL, instructions, &pMyData->virtreg);
         if (!reg3)
             {
             goto cleanup;
@@ -1390,8 +1401,8 @@ static int asm_relexp_value(PLLI instructions, IRINSTRUCTION* currentinstruction
     PVIRTREGINFO reg4;
     int iZero = 0;
     int bSuccess = 0;
-    OPCODE iop1;
-    OPCODE iop2;
+    condition_code iop1;
+    condition_code iop2;
     INSTRUCTION *asmInstr;
 
     pMyData = (PMYDATA)lpParam;
@@ -1528,33 +1539,33 @@ static int asm_relexp_value(PLLI instructions, IRINSTRUCTION* currentinstruction
     switch (ir_getOp(currentinstruction))
         {
         case IRINST_OPVALUE_EQUALS:
-            iop1 = opmoveq;
-            iop2 = opmovne;
+            iop1 = CONDITION_EQ;
+            iop2 = CONDITION_NE;
             break ;
 
         case IRINST_OPVALUE_NOTEQ:
-            iop1 = opmovne;
-            iop2 = opmoveq;
+            iop1 = CONDITION_NE;
+            iop2 = CONDITION_EQ;
             break ;
 
         case IRINST_OPVALUE_GT:
-            iop1 = opmovgt;
-            iop2 = opmovle;
+            iop1 = CONDITION_GT;
+            iop2 = CONDITION_LE;
             break ;
 
         case IRINST_OPVALUE_LT:
-            iop1 = opmovlt;
-            iop2 = opmovge;
+            iop1 = CONDITION_LT;
+            iop2 = CONDITION_GE;
             break ;
 
         case IRINST_OPVALUE_GTEQ:
-            iop1 = opmovge;
-            iop2 = opmovlt;
+            iop1 = CONDITION_GE;
+            iop2 = CONDITION_LT;
             break ;
 
         case IRINST_OPVALUE_LTEQ:
-            iop1 = opmovle;
-            iop2 = opmovgt;
+            iop1 = CONDITION_LE;
+            iop2 = CONDITION_GT;
             break ;
 
 
@@ -1579,7 +1590,8 @@ static int asm_relexp_value(PLLI instructions, IRINSTRUCTION* currentinstruction
         {
         return 0;
         }
-    asmInstr->iop = iop1;
+    asmInstr->iop = opmov;
+    asmInstr->cond = iop1;
     asmInstr->Args[0].argType = VIRTREGARG;
     asmInstr->Args[0].arg.virtreg = reg3;
     asmInstr->Args[1].argType = INTEGERARG;
@@ -1595,7 +1607,8 @@ static int asm_relexp_value(PLLI instructions, IRINSTRUCTION* currentinstruction
         {
         return 0;
         }
-    asmInstr->iop = iop2;
+    asmInstr->iop = opmov;
+    asmInstr->cond = iop2;
     asmInstr->Args[0].argType = VIRTREGARG;
     asmInstr->Args[0].arg.virtreg = reg3;
     asmInstr->Args[1].argType = INTEGERARG;
@@ -1670,7 +1683,7 @@ static int asm_relexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMT
     PVIRTREGINFO reg1;
     int iZero = 0;
     int bSuccess = 0;
-    OPCODE iop;
+    condition_code iop;
 
     pMyData = (PMYDATA)lpParam;
 
@@ -1807,27 +1820,27 @@ static int asm_relexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMT
     switch (ir_getOp(currentinstruction))
         {
         case IRINST_OP_EQUALS:
-            iop = opbeq;
+            iop = CONDITION_EQ;
             break ;
 
         case IRINST_OP_NOTEQ:
-            iop = opbne;
+            iop = CONDITION_NE;
             break ;
 
         case IRINST_OP_GT:
-            iop = opbgt;
+            iop = CONDITION_GT;
             break ;
 
         case IRINST_OP_LT:
-            iop = opblt;
+            iop = CONDITION_LT;
             break ;
 
         case IRINST_OP_GTEQ:
-            iop = opbge;
+            iop = CONDITION_GE;
             break ;
 
         case IRINST_OP_LTEQ:
-            iop = opble;
+            iop = CONDITION_LE;
             break ;
 
         default:
@@ -1846,7 +1859,7 @@ cleanup:
 
 static int asm_goto(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam)
 {
-    if (!addasmInstrbranches(instructions, opb, ir_GetBranchTarget(currentinstruction)))
+    if (!addasmInstrbranches(instructions, CONDITION_AL, ir_GetBranchTarget(currentinstruction)))
         {
         return 0;
         }    
@@ -2377,7 +2390,8 @@ static int asm_unaryexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SY
             {
             return 0;
             }
-        asmInstr->iop = opmoveq;
+        asmInstr->iop = opmov;
+        asmInstr->cond = CONDITION_EQ;
         asmInstr->Args[0].argType = VIRTREGARG;
         asmInstr->Args[0].arg.virtreg = reg2;
         asmInstr->Args[1].argType = INTEGERARG;
@@ -2393,7 +2407,8 @@ static int asm_unaryexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SY
             {
             return 0;
             }
-        asmInstr->iop = opmovne;
+        asmInstr->iop = opmov;
+        asmInstr->cond = CONDITION_NE;
         asmInstr->Args[0].argType = VIRTREGARG;
         asmInstr->Args[0].arg.virtreg = reg2;
         asmInstr->Args[1].argType = INTEGERARG;
@@ -3448,7 +3463,7 @@ int addasmInstrbx(PLLI instructions, int reg)
     return 1;
 }
 
-int addasmInstrbranches(PLLI instructions, OPCODE iop, unsigned long destination)
+int addasmInstrbranches(PLLI instructions, condition_code iop, unsigned long destination)
 {
     INSTRUCTION *asmInstr;
 
@@ -3457,7 +3472,8 @@ int addasmInstrbranches(PLLI instructions, OPCODE iop, unsigned long destination
         {
         return 0;
         }
-    asmInstr->iop = iop;
+    asmInstr->iop = opb;
+    asmInstr->cond = iop;
     asmInstr->Args[0].argType = INTEGERARG;
     asmInstr->Args[0].arg.int_val = destination;
     if (-1 == LinkListAppend(instructions, asmInstr))
@@ -5089,6 +5105,9 @@ static void PrintArg(FILE *stream, ARG *arg)
 void PrintasmInstr(FILE *stream, INSTRUCTION *asmInstr)
 {
     int    iCount;
+    char szFullName[512];
+
+    sprintf(szFullName, "%s%s%s", opCodeTab[asmInstr->iop], asmInstr->suffix ? "s" : "", asmInstr->cond ? condCodeTab[asmInstr->cond] : "");
 
     if (asmInstr->iop == oplabel)
         {
@@ -5105,7 +5124,7 @@ void PrintasmInstr(FILE *stream, INSTRUCTION *asmInstr)
         {
         if (asmInstr->nargs)
             {
-            fprintf ( stream, "    %-7s {", opCodeTab[asmInstr->iop]);
+            fprintf ( stream, "    %-7s {", szFullName);
             for( iCount = 0; iCount < asmInstr->nargs; iCount++ )
                 {
                 if (asmInstr->Args[iCount].argType != NOARG && iCount >= 1)
@@ -5121,21 +5140,21 @@ void PrintasmInstr(FILE *stream, INSTRUCTION *asmInstr)
         }
     else if ((asmInstr->iop == opmovw) && (asmInstr->Args[1].argType == SYMNAMEARG))
         {
-        fprintf ( stream, "    %-7s ", opCodeTab[asmInstr->iop]);
+        fprintf ( stream, "    %-7s ", szFullName);
         PrintArg(stream, &asmInstr->Args[0]);
         fprintf ( stream, ", #:lower16:");
         PrintArg(stream, &asmInstr->Args[1]);
         }
     else if ((asmInstr->iop == opmovt) && (asmInstr->Args[1].argType == SYMNAMEARG))
         {
-        fprintf ( stream, "    %-7s ", opCodeTab[asmInstr->iop]);
+        fprintf ( stream, "    %-7s ", szFullName);
         PrintArg(stream, &asmInstr->Args[0]);
         fprintf ( stream, ", #:upper16:");
         PrintArg(stream, &asmInstr->Args[1]);
         }
     else if ((asmInstr->iop == opldr) || (asmInstr->iop == opstr) || (asmInstr->iop == opvldr32) || (asmInstr->iop == opvstr32))
         {
-        fprintf ( stream, "    %-7s ", opCodeTab[asmInstr->iop]);
+        fprintf ( stream, "    %-7s ", szFullName);
         PrintArg(stream, &asmInstr->Args[0]);
         fprintf ( stream, ", [");
         PrintArg(stream, &asmInstr->Args[1]);
@@ -5162,15 +5181,9 @@ void PrintasmInstr(FILE *stream, INSTRUCTION *asmInstr)
             }
         PrintArg(stream, &asmInstr->Args[1]);
         }
-    else if ((asmInstr->iop == opb) ||
-             (asmInstr->iop == opbeq) ||
-             (asmInstr->iop == opbne) ||
-             (asmInstr->iop == opbge) ||
-             (asmInstr->iop == opbgt) ||
-             (asmInstr->iop == opble) ||
-             (asmInstr->iop == opblt))
+    else if (asmInstr->iop == opb)
         {
-        fprintf ( stream, "    %-7s .L%u", opCodeTab[asmInstr->iop], asmInstr->Args[0].arg.int_val);
+        fprintf ( stream, "    %-7s .L%u", szFullName, asmInstr->Args[0].arg.int_val);
         }
     else if (asmInstr->iop == opDBG)
         {
@@ -5188,7 +5201,7 @@ void PrintasmInstr(FILE *stream, INSTRUCTION *asmInstr)
         }
     else
         {
-        fprintf ( stream, "    %-7s ", opCodeTab[asmInstr->iop]);
+        fprintf ( stream, "    %-7s ", szFullName);
         for( iCount = 0; iCount < asmInstr->nargs; iCount++ )
             {
             if (asmInstr->Args[iCount].argType != NOARG && iCount >= 1)
@@ -5898,7 +5911,7 @@ INSTRUCTION* asmcopy(INSTRUCTION* src)
     return lpBuffer;
 }
 
-static PVIRTREGINFO expand_binop(PVIRTREGINFO op0, void* op1, int IsImm, OPCODE op, PLLI instructions, PDYNAMIC_ARRAY virtregs)
+static PVIRTREGINFO expand_binop(PVIRTREGINFO op0, void* op1, int IsImm, OPCODE op, int suffix, condition_code cond, PLLI instructions, PDYNAMIC_ARRAY virtregs)
 {
     INSTRUCTION* insn;
     PVIRTREGINFO target = NULL;
@@ -5919,6 +5932,8 @@ static PVIRTREGINFO expand_binop(PVIRTREGINFO op0, void* op1, int IsImm, OPCODE
         goto cleanup;
         }
     insn->iop = op;
+    insn->cond = cond;
+    insn->suffix = suffix;
     insn->Args[0].argType = VIRTREGARG;
     insn->Args[0].arg.virtreg = target;
     insn->Args[1].argType = VIRTREGARG;
@@ -6271,45 +6286,71 @@ expand_divmod (PVIRTREGINFO op0, void* op1, int IsImm, int mod_flag, PLLI instru
             {
   /* 如果log>= 0,则通过移位来实现。
      我们必须根据除数加减某个数来纠正被除数,以实现代码指定的舍入。  */
-            insn = AllocasmInstr(2);
-            if (!insn)
+            if (!mod_flag)
                 {
-                goto Error;
-                }
-            insn->iop =  opcmp;
-            insn->Args[0].argType = VIRTREGARG;
-            insn->Args[0].arg.virtreg = op0;
-            insn->Args[1].argType = INTEGERARG;
-            insn->Args[1].arg.int_val = 0;
-            if (-1 == LinkListAppend(instructions, insn))
-                {
-                free(insn);
-                goto Error;
-                }
+                iVal = *(int*) op1 - 1;
+                reg1 = expand_binop(op0, &iVal, 1, opadd, 0, CONDITION_AL, instructions, virtregs);
+                if (!reg1)
+                    {
+                    goto Error;
+                    }
 
-            iVal = *(int*) op1 - 1;
-            temp = expand_binop(op0, &iVal, 1, opadd, instructions, virtregs);
-            if (!temp)
-                {
-                goto Error;
-                }
+                insn = AllocasmInstr(2);
+                if (!insn)
+                    {
+                    goto Error;
+                    }
+                insn->iop =  opcmp;
+                insn->Args[0].argType = VIRTREGARG;
+                insn->Args[0].arg.virtreg = op0;
+                insn->Args[1].argType = INTEGERARG;
+                insn->Args[1].arg.int_val = 0;
+                if (-1 == LinkListAppend(instructions, insn))
+                    {
+                    free(insn);
+                    goto Error;
+                    }
 
-            insn = AllocasmInstr(2);
-            if (!insn)
-                {
-                goto Error;
-                }
-            insn->iop =  opmovge;
-            insn->Args[0].argType = VIRTREGARG;
-            insn->Args[0].arg.virtreg = temp;
-            insn->Args[1].argType = VIRTREGARG;
-            insn->Args[1].arg.virtreg = op0;
-            if (-1 == LinkListAppend(instructions, insn))
-                {
-                free(insn);
-                goto Error;
-                }
+                temp = getReg(virtregs, NULL, 0, NULL, 0, 0, op0->isfloat ,&IsPresent);
+                if (!reg1)
+                    {
+                    goto Error;
+                    }
 
+                insn = AllocasmInstr(2);
+                if (!insn)
+                    {
+                    goto Error;
+                    }
+                insn->iop =  opmov;
+                insn->cond =  CONDITION_LT;
+                insn->Args[0].argType = VIRTREGARG;
+                insn->Args[0].arg.virtreg = temp;
+                insn->Args[1].argType = VIRTREGARG;
+                insn->Args[1].arg.virtreg = reg1;
+                if (-1 == LinkListAppend(instructions, insn))
+                    {
+                    free(insn);
+                    goto Error;
+                    }
+
+                insn = AllocasmInstr(2);
+                if (!insn)
+                    {
+                    goto Error;
+                    }
+                insn->iop =  opmov;
+                insn->cond =  CONDITION_GE;
+                insn->Args[0].argType = VIRTREGARG;
+                insn->Args[0].arg.virtreg = temp;
+                insn->Args[1].argType = VIRTREGARG;
+                insn->Args[1].arg.virtreg = op0;
+                if (-1 == LinkListAppend(instructions, insn))
+                    {
+                    free(insn);
+                    goto Error;
+                    }
+                }
             }
         else
             { // 将除数放在寄存器中
@@ -6347,12 +6388,44 @@ expand_divmod (PVIRTREGINFO op0, void* op1, int IsImm, int mod_flag, PLLI instru
 
 	if (mod_flag && log>=0)
 		{
+        iVal = 0;
+        temp = expand_binop(op0, &iVal, 1, oprsb, 1, CONDITION_AL, instructions, virtregs);
+        if (!temp)
+            {
+            goto Error;
+            }
+
         iVal = *(int*) op1 - 1;
-        target = expand_binop(op0, &iVal, 1, opand, instructions, virtregs);
+        target = expand_binop(op0, &iVal, 1, opand, 0, CONDITION_AL, instructions, virtregs);
         if (!target)
             {
             goto Error;
             }
+        reg1 = expand_binop(temp, &iVal, 1, opand, 0, CONDITION_AL, instructions, virtregs);
+        if (!reg1)
+            {
+            goto Error;
+            }
+
+        insn = AllocasmInstr(3);
+        if (!insn)
+            {
+            goto Error;
+            }
+        insn->iop =  oprsb;
+        insn->cond =  CONDITION_PL;
+        insn->Args[0].argType = VIRTREGARG;
+        insn->Args[0].arg.virtreg = target;
+        insn->Args[1].argType = VIRTREGARG;
+        insn->Args[1].arg.virtreg = reg1;
+        insn->Args[2].argType = INTEGERARG;
+        insn->Args[2].arg.int_val = 0;
+        if (-1 == LinkListAppend(instructions, insn))
+            {
+            free(insn);
+            goto Error;
+            }
+
         goto Success;
 		}
 
@@ -6374,7 +6447,7 @@ expand_divmod (PVIRTREGINFO op0, void* op1, int IsImm, int mod_flag, PLLI instru
         insn->Args[0].argType = VIRTREGARG;
         insn->Args[0].arg.virtreg = target;
         insn->Args[1].argType = VIRTREGARG;
-        insn->Args[1].arg.virtreg = op0;
+        insn->Args[1].arg.virtreg = temp;
         insn->Args[2].argType = INTEGERARG;
         insn->Args[2].arg.int_val = exact_log2 (*(int*) op1);
         if (-1 == LinkListAppend(instructions, insn))
diff --git a/back/ARMv7/regalloc.c b/back/ARMv7/regalloc.c
index 813673f5ea2153ef6181af08466a0f91072763a0..49913dab165ea34f7d0b59baa61b1f51d0225609 100644
--- a/back/ARMv7/regalloc.c
+++ b/back/ARMv7/regalloc.c
@@ -441,18 +441,6 @@ static int IsInputOpr(OPCODE iop, int iarg)
             iResult = 1;
             break;
 
-        case opmoveq:
-            /* fall through */
-        case opmovne:
-            /* fall through */
-        case opmovle:
-            /* fall through */
-        case opmovgt:
-            /* fall through */
-        case opmovlt:
-            /* fall through */
-        case opmovge:
-            /* fall through */
         case opuxtb:
             if (iarg != 0)
                 {
@@ -487,18 +475,6 @@ static int IsInputOpr(OPCODE iop, int iarg)
             /* fall through */
         case  opbx:
             /* fall through */
-        case  opbeq:
-            /* fall through */
-        case  opbne:
-            /* fall through */
-        case  opblt:
-            /* fall through */
-        case  opble:
-            /* fall through */
-        case  opbgt:
-            /* fall through */
-        case  opbge:
-            /* fall through */
         case  opb:
             /* fall through */
         case  opbl:
diff --git a/compiler.exe b/compiler.exe
index 91f655dff35611e362856eed35d92ee058b4a974..3ea7c68a8cbeaf9ac95ded054a75d51fc0ace4cf 100644
Binary files a/compiler.exe and b/compiler.exe differ
diff --git a/front/IRInst.c b/front/IRInst.c
index 1a8d06a62556084e98d6fa45ffb2898b66d705bb..4b9307e7622544666aecb22f5ac25b120f434f5f 100644
--- a/front/IRInst.c
+++ b/front/IRInst.c
@@ -350,6 +350,15 @@ void PrintInstruction(FILE *stream, IRINSTRUCTION *inst, int fEscape, int fRenam
                         }
                     break;
             }
+        if (inst->iop == IRINST_OP_ARRAYASSIGN)
+            {
+            fprintf(stream, ", ");
+            PrintSymbol(stream, inst->iarg3);
+            if (fRename && inst->iarg3)
+                {
+                fprintf(stream, "'%d", ir_GetNumber(inst, 3));
+                }
+            }
         }
 
     fprintf(stream, ")");
@@ -643,7 +652,6 @@ int ir_isDef(IRINSTRUCTION *inst, int iArg)
     iop = ir_getOp(inst);
     switch (iop)
         {
-        case IRINST_OP_PLUS:
         case IRINST_OP_MULT:
         case IRINST_OP_MINUS:
         case IRINST_OP_DIV:
@@ -669,6 +677,18 @@ int ir_isDef(IRINSTRUCTION *inst, int iArg)
                 }
             break;
 
+        case IRINST_OP_PLUS:
+            if (iArg == 2)
+                {
+                bResult = 1;
+                }
+            if (iArg == 0 && !ir_IsArgFloat(inst, 1) && !ir_IsArgInteger(inst, 1) && 
+                !SymIsConst(ir_GetArgVoidPtr(inst, 1), NULL, NULL) && DynamicArrayGetCount(Get_Dope(ir_GetArgVoidPtr(inst, 1))))
+                {
+                bResult = 1;
+                }
+            break;
+
         case IRINST_OP_FUNC_CALL:
             if ((iArg == 2) && (ir_GetDstVoidPtr(inst) != NULL))
                 {
@@ -709,10 +729,16 @@ int ir_GetNumber(IRINSTRUCTION *inst, int iArg)
         {
         return inst->number3;
         }
-    else
+    else if (iArg == 3)
         {
         return inst->number4;
         }
+    else
+        {
+        internal_error(NULL, "Fatal error on line %u of %s.", __LINE__, __FILE__);
+        return -1;
+        }
+    
 }
 
 void ir_SetNumber(IRINSTRUCTION *inst, int iArg, int number)
@@ -729,10 +755,14 @@ void ir_SetNumber(IRINSTRUCTION *inst, int iArg, int number)
         {
         inst->number3 = number;
         }
-    else
+    else if (iArg == 3)
         {
         inst->number4 = number;
         }
+    else
+        {
+        internal_error(NULL, "Fatal error on line %u of %s.", __LINE__, __FILE__);
+        }
 }
 
 void ir_SetArgVoidPtr(IRINSTRUCTION* inst, int iArg, void* lpvoid)
@@ -765,7 +795,7 @@ void ir_GetOperand(IRINSTRUCTION *inst, int iArg, ExpType *lpType, int *isImmedi
         if (!ir_IsArgFloat(inst, 1) && !ir_IsArgInteger(inst, 1))
             {
             psyment = ir_GetArgVoidPtr(inst, 1);
-            if (!SymIsConst(psyment, lpType, lpBuffer) || DynamicArrayGetCount(Get_Dope(psyment)))
+            if (DynamicArrayGetCount(Get_Dope(psyment)) || !SymIsConst(psyment, lpType, lpBuffer))
                 {
                 *isImmediate = 0;
                 *(SYMENT**)lpBuffer = psyment;
@@ -794,7 +824,7 @@ void ir_GetOperand(IRINSTRUCTION *inst, int iArg, ExpType *lpType, int *isImmedi
         if (!ir_IsArgFloat(inst, 0) && !ir_IsArgInteger(inst, 0))
             {
             psyment = ir_GetArgVoidPtr(inst, 0);
-            if (!SymIsConst(psyment, lpType, lpBuffer) || DynamicArrayGetCount(Get_Dope(psyment)))
+            if ( DynamicArrayGetCount(Get_Dope(psyment)) || !SymIsConst(psyment, lpType, lpBuffer) )
                 {
                 *isImmediate = 0;
                 *(SYMENT**)lpBuffer = psyment;
@@ -960,6 +990,7 @@ void swap_operands(InterCode *g_code)
                     insn->fIsArg2Float = 0;
                     }
 
+			//	警告:下面这些memcpy不再可用。它们在本地或者树莓派上不会引起崩溃,但在评测机上不总是如此。
                 // uiSize = (char *)&(P->fIsArg2Integer) - (char *)&(P->fIsArg1Integer);
                 // memcpy ( &Swap.fIsArg2Integer, &insn->fIsArg1Integer, uiSize ) ;
                 // memcpy ( &Swap.fIsArg1Integer, &insn->fIsArg2Integer, uiSize ) ;
@@ -994,6 +1025,50 @@ void swap_operands(InterCode *g_code)
         }
 }
 
+/// @brief 找到指针类型的参数所指向的数组。
+/// @param insn 一条中间代码
+SYMENT* FinddefinedArray(IRINSTRUCTION* insn)
+{
+    IRInstOperator iop  ;
+    SYMENT* psyment;
+
+    iop = ir_getOp(insn);
+
+	if (iop != IRINST_OP_PARAM)
+		{
+		return NULL;
+		}
+
+	if (ir_IsArgFloat(insn, 1) || ir_IsArgInteger(insn, 1) || SymIsConst(ir_GetArgVoidPtr(insn, 1), NULL, NULL))
+		{
+		return NULL;
+		}
+    psyment = ir_GetArgVoidPtr(insn, 1);
+    return SymGetPointTo(psyment);
+}
+
+/// @brief 找到一条参数中间指令所属的函数调用。
+/// @param insn 一条参数中间代码
+IRINSTRUCTION* FindParamFunc(IRINSTRUCTION* insn)
+{
+    LIST_ITERATOR iterator;
+    IRINSTRUCTION* inst;
+    int bFound = 0;
+
+    List_TRAVERSE(bb_GetInsts(ir_GetContainer(insn)), inst, &iterator)
+        {
+        if (insn == inst)
+            {
+            bFound = 1;
+            }
+        if (bFound && ir_getOp(inst)==IRINST_OP_FUNC_CALL)
+            {
+            return inst;
+            }
+        }
+    return NULL;
+}
+
 #if defined( WITH_PRINTIR_NEW )
 
 static void PrintAllDeclarations(FILE *stream, SYMTAB *SymTable)
diff --git a/front/genIR.c b/front/genIR.c
index dcd981266c336ac66c37eb18f606b1c54f8bc7b1..ad6c5ded6087fcf0296c88c32bcb358ec32878bd 100644
--- a/front/genIR.c
+++ b/front/genIR.c
@@ -3241,6 +3241,7 @@ static int ir_funccall(TreeNode * pv)
                     return 0;
                     }
                 memset(&symParam, 0, sizeof(symParam));
+                SymSetPointTo(psyment, Ast_GetPlace(pvisit));
                 if (!Ast_AddInst(pv, &g_code, &labelCount, IRINST_OP_PLUS, Ast_GetPlace(pvisit), Ast_GetOffset(pvisit), psyment))
                     { 
                     return 0;
diff --git a/front/grammar.tab.c b/front/grammar.tab.c
index ec5a915d7bef0515e6df5bcf6f0c034aa7f3b9db..ff9b133661c11ef7ac5dfe59200a6d7067a218cb 100644
--- a/front/grammar.tab.c
+++ b/front/grammar.tab.c
@@ -67,7 +67,7 @@
 
 
 /* First part of user prologue.  */
-#line 7 "./front/grammar.y"
+#line 7 ".\\front\\grammar.y"
  
 #include "compiler.h"
 
@@ -78,7 +78,7 @@
 #define YYDEBUG 1
 
 
-#line 82 "./front/grammar.tab.c"
+#line 82 ".\\front\\grammar.tab.c"
 
 # ifndef YY_CAST
 #  ifdef __cplusplus
@@ -1321,7 +1321,7 @@ yyreduce:
   switch (yyn)
     {
   case 2: /* CompUnit: FuncDef  */
-#line 147 "./front/grammar.y"
+#line 147 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : CompUnit -> FuncDef\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1339,11 +1339,11 @@ yyreduce:
         }
       g_savedTree = (yyval.asttreenode);
     }
-#line 1343 "./front/grammar.tab.c"
+#line 1343 ".\\front\\grammar.tab.c"
     break;
 
   case 3: /* CompUnit: CompUnit FuncDef  */
-#line 165 "./front/grammar.y"
+#line 165 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : CompUnit -> CompUnit FuncDef\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
@@ -1353,11 +1353,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1357 "./front/grammar.tab.c"
+#line 1357 ".\\front\\grammar.tab.c"
     break;
 
   case 4: /* CompUnit: Decl  */
-#line 175 "./front/grammar.y"
+#line 175 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : CompUnit -> Decl\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1375,11 +1375,11 @@ yyreduce:
         }
       g_savedTree = (yyval.asttreenode);
     }
-#line 1379 "./front/grammar.tab.c"
+#line 1379 ".\\front\\grammar.tab.c"
     break;
 
   case 5: /* CompUnit: CompUnit Decl  */
-#line 193 "./front/grammar.y"
+#line 193 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : CompUnit -> CompUnit Decl\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
@@ -1389,49 +1389,49 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1393 "./front/grammar.tab.c"
+#line 1393 ".\\front\\grammar.tab.c"
     break;
 
   case 6: /* Decl: ConstDecl  */
-#line 207 "./front/grammar.y"
+#line 207 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : Decl -> ConstDecl\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 1402 "./front/grammar.tab.c"
+#line 1402 ".\\front\\grammar.tab.c"
     break;
 
   case 7: /* Decl: VarDecl  */
-#line 212 "./front/grammar.y"
+#line 212 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : Decl -> VarDecl\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 1411 "./front/grammar.tab.c"
+#line 1411 ".\\front\\grammar.tab.c"
     break;
 
   case 8: /* Decl: FuncDecl  */
-#line 217 "./front/grammar.y"
+#line 217 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : Decl -> FuncDecl\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 1420 "./front/grammar.tab.c"
+#line 1420 ".\\front\\grammar.tab.c"
     break;
 
   case 9: /* ConstDecl: "const" BType ConstDefGroup ";"  */
-#line 226 "./front/grammar.y"
+#line 226 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : ConstDecl -> \"const\" BType ConstDefGroup \";\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
       SetBasicType((yyval.asttreenode), (yyvsp[-2].integer));
       SetNodeType((yyval.asttreenode), AT_ConstDecl);
     }
-#line 1431 "./front/grammar.tab.c"
+#line 1431 ".\\front\\grammar.tab.c"
     break;
 
   case 10: /* ConstDefGroup: ConstDefGroup "," ConstDef  */
-#line 236 "./front/grammar.y"
+#line 236 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : ConstDefGroup -> ConstDefGroup \",\" ConstDef\n", ++nCount));
       (yyval.asttreenode)= (yyvsp[-2].asttreenode);
@@ -1441,11 +1441,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1445 "./front/grammar.tab.c"
+#line 1445 ".\\front\\grammar.tab.c"
     break;
 
   case 11: /* ConstDefGroup: ConstDef  */
-#line 246 "./front/grammar.y"
+#line 246 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : ConstDefGroup -> ConstDef\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1461,29 +1461,29 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1465 "./front/grammar.tab.c"
+#line 1465 ".\\front\\grammar.tab.c"
     break;
 
   case 12: /* BType: "int"  */
-#line 266 "./front/grammar.y"
+#line 266 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : BType -> \"int\"\n", ++nCount));
       (yyval.integer) = Integer;
     }
-#line 1474 "./front/grammar.tab.c"
+#line 1474 ".\\front\\grammar.tab.c"
     break;
 
   case 13: /* BType: "float"  */
-#line 271 "./front/grammar.y"
+#line 271 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : BType -> \"float\"\n", ++nCount));
       (yyval.integer) = Float;
     }
-#line 1483 "./front/grammar.tab.c"
+#line 1483 ".\\front\\grammar.tab.c"
     break;
 
   case 14: /* ConstDef: Ident ConstExpGroup "=" ConstInitVal  */
-#line 280 "./front/grammar.y"
+#line 280 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : ConstDef -> Ident ConstExpGroup \"=\" ConstInitVal\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-3].asttreenode);
@@ -1500,11 +1500,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1504 "./front/grammar.tab.c"
+#line 1504 ".\\front\\grammar.tab.c"
     break;
 
   case 15: /* ConstExpGroup: "[" ConstExp "]" ConstExpGroup  */
-#line 300 "./front/grammar.y"
+#line 300 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : ConstExpGroup -> \"[\" ConstExp \"]\" ConstExpGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -1514,11 +1514,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1518 "./front/grammar.tab.c"
+#line 1518 ".\\front\\grammar.tab.c"
     break;
 
   case 16: /* ConstExpGroup: %empty  */
-#line 310 "./front/grammar.y"
+#line 310 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : ConstExpGroup -> (null)\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1530,11 +1530,11 @@ yyreduce:
       SetOriginalType((yyval.asttreenode), ConstExpGroupK);
       SetNodeType((yyval.asttreenode), AT_ConstExpGroup);
     }
-#line 1534 "./front/grammar.tab.c"
+#line 1534 ".\\front\\grammar.tab.c"
     break;
 
   case 17: /* ConstInitVal: ConstExp  */
-#line 326 "./front/grammar.y"
+#line 326 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : ConstInitVal -> ConstExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1551,11 +1551,11 @@ yyreduce:
       SetNodeType((yyval.asttreenode), AT_ConstInitVal);
       SetOriginalType((yyval.asttreenode),ConstInitValK);
     }
-#line 1555 "./front/grammar.tab.c"
+#line 1555 ".\\front\\grammar.tab.c"
     break;
 
   case 18: /* ConstInitVal: "{" "}"  */
-#line 343 "./front/grammar.y"
+#line 343 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : ConstInitVal -> \"{\" \"}\"\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1567,22 +1567,22 @@ yyreduce:
       SetOriginalType((yyval.asttreenode),ConstInitValK);
       SetNodeType((yyval.asttreenode), AT_ConstInitVal);
     }
-#line 1571 "./front/grammar.tab.c"
+#line 1571 ".\\front\\grammar.tab.c"
     break;
 
   case 19: /* ConstInitVal: "{" ConstInitValGroup "}"  */
-#line 355 "./front/grammar.y"
+#line 355 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : ConstInitVal -> \"{\" ConstInitValGroup \"}\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
       SetOriginalType((yyval.asttreenode),ConstInitValK);
       SetNodeType((yyval.asttreenode), AT_ConstInitVal);
     }
-#line 1582 "./front/grammar.tab.c"
+#line 1582 ".\\front\\grammar.tab.c"
     break;
 
   case 20: /* ConstInitValGroup: ConstInitVal dummy1  */
-#line 365 "./front/grammar.y"
+#line 365 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : ConstInitValGroup -> ConstInitVal dummy1\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -1592,11 +1592,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1596 "./front/grammar.tab.c"
+#line 1596 ".\\front\\grammar.tab.c"
     break;
 
   case 21: /* dummy1: "," ConstInitVal dummy1  */
-#line 378 "./front/grammar.y"
+#line 378 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : dummy1 -> \",\" ConstInitVal dummy1\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -1606,11 +1606,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1610 "./front/grammar.tab.c"
+#line 1610 ".\\front\\grammar.tab.c"
     break;
 
   case 22: /* dummy1: %empty  */
-#line 388 "./front/grammar.y"
+#line 388 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : dummy1 -> (null)\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1621,11 +1621,11 @@ yyreduce:
         }
       SetOriginalType((yyval.asttreenode), ConstInitValGroupK);
     }
-#line 1625 "./front/grammar.tab.c"
+#line 1625 ".\\front\\grammar.tab.c"
     break;
 
   case 23: /* VarDecl: BType VarDef VarDefGroup ";"  */
-#line 403 "./front/grammar.y"
+#line 403 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : VarDecl -> BType VarDef VarDefGroup \";\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
@@ -1637,11 +1637,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1641 "./front/grammar.tab.c"
+#line 1641 ".\\front\\grammar.tab.c"
     break;
 
   case 24: /* VarDefGroup: "," VarDef VarDefGroup  */
-#line 418 "./front/grammar.y"
+#line 418 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : VarDefGroup -> \",\" VarDef VarDefGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -1651,11 +1651,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1655 "./front/grammar.tab.c"
+#line 1655 ".\\front\\grammar.tab.c"
     break;
 
   case 25: /* VarDefGroup: %empty  */
-#line 428 "./front/grammar.y"
+#line 428 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : VarDefGroup -> (null)\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1666,11 +1666,11 @@ yyreduce:
         }
       SetOriginalType((yyval.asttreenode), VarDeclK);
     }
-#line 1670 "./front/grammar.tab.c"
+#line 1670 ".\\front\\grammar.tab.c"
     break;
 
   case 26: /* VarDef: Ident ConstExpGroup  */
-#line 443 "./front/grammar.y"
+#line 443 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : VarDef -> Ident ConstExpGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
@@ -1682,11 +1682,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1686 "./front/grammar.tab.c"
+#line 1686 ".\\front\\grammar.tab.c"
     break;
 
   case 27: /* VarDef: Ident ConstExpGroup "=" InitVal  */
-#line 455 "./front/grammar.y"
+#line 455 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : VarDef -> Ident ConstExpGroup \"=\" InitVal\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-3].asttreenode);
@@ -1703,11 +1703,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1707 "./front/grammar.tab.c"
+#line 1707 ".\\front\\grammar.tab.c"
     break;
 
   case 28: /* InitVal: Exp  */
-#line 476 "./front/grammar.y"
+#line 476 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : InitVal -> Exp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1724,11 +1724,11 @@ yyreduce:
       SetNodeType((yyval.asttreenode), AT_InitVal);
       SetOriginalType((yyval.asttreenode),InitValK);
     }
-#line 1728 "./front/grammar.tab.c"
+#line 1728 ".\\front\\grammar.tab.c"
     break;
 
   case 29: /* InitVal: "{" "}"  */
-#line 493 "./front/grammar.y"
+#line 493 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : InitVal -> \"{\" \"}\"\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1740,11 +1740,11 @@ yyreduce:
       SetOriginalType((yyval.asttreenode),InitValK);
       SetNodeType((yyval.asttreenode), AT_InitVal);
     }
-#line 1744 "./front/grammar.tab.c"
+#line 1744 ".\\front\\grammar.tab.c"
     break;
 
   case 30: /* InitVal: "{" InitVal InitValGroup "}"  */
-#line 505 "./front/grammar.y"
+#line 505 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : InitVal -> \"{\" InitVal InitValGroup \"}\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
@@ -1755,11 +1755,11 @@ yyreduce:
         }
       SetNodeType((yyval.asttreenode), AT_InitVal);
     }
-#line 1759 "./front/grammar.tab.c"
+#line 1759 ".\\front\\grammar.tab.c"
     break;
 
   case 31: /* InitValGroup: "," InitVal InitValGroup  */
-#line 519 "./front/grammar.y"
+#line 519 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : InitValGroup -> \",\" InitVal InitValGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -1769,11 +1769,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1773 "./front/grammar.tab.c"
+#line 1773 ".\\front\\grammar.tab.c"
     break;
 
   case 32: /* InitValGroup: %empty  */
-#line 529 "./front/grammar.y"
+#line 529 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : InitValGroup -> (null)\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1784,11 +1784,11 @@ yyreduce:
         }
       SetOriginalType((yyval.asttreenode),InitValK);
     }
-#line 1788 "./front/grammar.tab.c"
+#line 1788 ".\\front\\grammar.tab.c"
     break;
 
   case 33: /* FuncDef: BType Ident "(" ")" Block  */
-#line 544 "./front/grammar.y"
+#line 544 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncDef -> BType Ident \"(\" \")\" Block\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-3].asttreenode);
@@ -1814,11 +1814,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1818 "./front/grammar.tab.c"
+#line 1818 ".\\front\\grammar.tab.c"
     break;
 
   case 34: /* FuncDef: BType Ident "(" FuncFParams ")" Block  */
-#line 570 "./front/grammar.y"
+#line 570 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncDef -> BType Ident \"(\" FuncFParams \")\" Block\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-4].asttreenode);
@@ -1836,11 +1836,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1840 "./front/grammar.tab.c"
+#line 1840 ".\\front\\grammar.tab.c"
     break;
 
   case 35: /* FuncDef: "void" Ident "(" ")" Block  */
-#line 588 "./front/grammar.y"
+#line 588 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncDef -> \"void\" Ident \"(\" \")\" Block\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-3].asttreenode);
@@ -1866,11 +1866,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1870 "./front/grammar.tab.c"
+#line 1870 ".\\front\\grammar.tab.c"
     break;
 
   case 36: /* FuncDef: "void" Ident "(" FuncFParams ")" Block  */
-#line 614 "./front/grammar.y"
+#line 614 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncDef -> \"void\" Ident \"(\" FuncFParams \")\" Block\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-4].asttreenode);
@@ -1888,11 +1888,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1892 "./front/grammar.tab.c"
+#line 1892 ".\\front\\grammar.tab.c"
     break;
 
   case 37: /* FuncFParams: FuncFParam FuncFParamGroup  */
-#line 636 "./front/grammar.y"
+#line 636 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncFParams -> FuncFParam FuncFParamGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -1902,11 +1902,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1906 "./front/grammar.tab.c"
+#line 1906 ".\\front\\grammar.tab.c"
     break;
 
   case 38: /* FuncFParamGroup: "," FuncFParam FuncFParamGroup  */
-#line 649 "./front/grammar.y"
+#line 649 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncFParamGroup -> \",\" FuncFParam FuncFParamGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -1916,11 +1916,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 1920 "./front/grammar.tab.c"
+#line 1920 ".\\front\\grammar.tab.c"
     break;
 
   case 39: /* FuncFParamGroup: %empty  */
-#line 659 "./front/grammar.y"
+#line 659 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncFParamGroup -> (null)\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1932,11 +1932,11 @@ yyreduce:
       SetOriginalType((yyval.asttreenode), FuncFParamsK);
       SetNodeType((yyval.asttreenode), AT_FuncFParams);
     }
-#line 1936 "./front/grammar.tab.c"
+#line 1936 ".\\front\\grammar.tab.c"
     break;
 
   case 40: /* FuncFParam: BType  */
-#line 675 "./front/grammar.y"
+#line 675 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : FuncFParam -> BType\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -1950,11 +1950,11 @@ yyreduce:
       SetLineno((yyval.asttreenode), LineNum);
       SetBasicType((yyval.asttreenode), (yyvsp[0].integer));
     }
-#line 1954 "./front/grammar.tab.c"
+#line 1954 ".\\front\\grammar.tab.c"
     break;
 
   case 41: /* FuncFParam: BType Ident  */
-#line 689 "./front/grammar.y"
+#line 689 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : FuncFParam -> BType Ident\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -1962,11 +1962,11 @@ yyreduce:
       SetNodeType((yyval.asttreenode), AT_FuncFParam);
       SetBasicType((yyval.asttreenode), (yyvsp[-1].integer));
     }
-#line 1966 "./front/grammar.tab.c"
+#line 1966 ".\\front\\grammar.tab.c"
     break;
 
   case 42: /* FuncFParam: BType Ident "[" "]" ExpGroup  */
-#line 697 "./front/grammar.y"
+#line 697 ".\\front\\grammar.y"
     {
       TreeNode* temp;
       int tempValue;
@@ -2004,11 +2004,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2008 "./front/grammar.tab.c"
+#line 2008 ".\\front\\grammar.tab.c"
     break;
 
   case 43: /* ExpGroup: "[" Exp "]" ExpGroup  */
-#line 738 "./front/grammar.y"
+#line 738 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : ExpGroup -> \"[\" Exp \"]\" ExpGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -2018,11 +2018,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2022 "./front/grammar.tab.c"
+#line 2022 ".\\front\\grammar.tab.c"
     break;
 
   case 44: /* ExpGroup: %empty  */
-#line 748 "./front/grammar.y"
+#line 748 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : ExpGroup -> (null)\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2032,21 +2032,21 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2036 "./front/grammar.tab.c"
+#line 2036 ".\\front\\grammar.tab.c"
     break;
 
   case 45: /* Block: "{" BlockItemGroup "}"  */
-#line 762 "./front/grammar.y"
+#line 762 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Block -> \"{\" BlockItemGroup \"}\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
       SetNodeType((yyval.asttreenode), AT_Block);
     }
-#line 2046 "./front/grammar.tab.c"
+#line 2046 ".\\front\\grammar.tab.c"
     break;
 
   case 46: /* BlockItemGroup: BlockItem BlockItemGroup  */
-#line 771 "./front/grammar.y"
+#line 771 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : BlockItemGroup -> BlockItem BlockItemGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -2056,11 +2056,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2060 "./front/grammar.tab.c"
+#line 2060 ".\\front\\grammar.tab.c"
     break;
 
   case 47: /* BlockItemGroup: %empty  */
-#line 781 "./front/grammar.y"
+#line 781 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : BlockItemGroup -> (null)\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2071,29 +2071,29 @@ yyreduce:
         }
       SetOriginalType((yyval.asttreenode),BlockK);
     }
-#line 2075 "./front/grammar.tab.c"
+#line 2075 ".\\front\\grammar.tab.c"
     break;
 
   case 48: /* BlockItem: Decl  */
-#line 796 "./front/grammar.y"
+#line 796 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : BlockItem -> Decl\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2084 "./front/grammar.tab.c"
+#line 2084 ".\\front\\grammar.tab.c"
     break;
 
   case 49: /* BlockItem: Stmt  */
-#line 801 "./front/grammar.y"
+#line 801 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : BlockItem -> Stmt\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2093 "./front/grammar.tab.c"
+#line 2093 ".\\front\\grammar.tab.c"
     break;
 
   case 50: /* Stmt: LVal "=" Exp ";"  */
-#line 810 "./front/grammar.y"
+#line 810 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> LVal \"=\" Exp \";\"\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2115,11 +2115,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2119 "./front/grammar.tab.c"
+#line 2119 ".\\front\\grammar.tab.c"
     break;
 
   case 51: /* Stmt: ";"  */
-#line 832 "./front/grammar.y"
+#line 832 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> \";\"\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2131,30 +2131,30 @@ yyreduce:
       SetOriginalType((yyval.asttreenode), StmtK);
       SetNodeType((yyval.asttreenode), AT_EmptyStmt);
     }
-#line 2135 "./front/grammar.tab.c"
+#line 2135 ".\\front\\grammar.tab.c"
     break;
 
   case 52: /* Stmt: Exp ";"  */
-#line 844 "./front/grammar.y"
+#line 844 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> Exp \";\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
     }
-#line 2144 "./front/grammar.tab.c"
+#line 2144 ".\\front\\grammar.tab.c"
     break;
 
   case 53: /* Stmt: Block  */
-#line 849 "./front/grammar.y"
+#line 849 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> Block\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
       SetNodeType((yyval.asttreenode), AT_Block);
     }
-#line 2154 "./front/grammar.tab.c"
+#line 2154 ".\\front\\grammar.tab.c"
     break;
 
   case 54: /* Stmt: "if" "(" Cond ")" Stmt  */
-#line 855 "./front/grammar.y"
+#line 855 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> \"if\" \"(\" Cond \")\" Stmt\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2176,11 +2176,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2180 "./front/grammar.tab.c"
+#line 2180 ".\\front\\grammar.tab.c"
     break;
 
   case 55: /* Stmt: "if" "(" Cond ")" Stmt "else" Stmt  */
-#line 877 "./front/grammar.y"
+#line 877 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> \"if\" \"(\" Cond \")\" Stmt \"else\" Stmt\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2207,11 +2207,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2211 "./front/grammar.tab.c"
+#line 2211 ".\\front\\grammar.tab.c"
     break;
 
   case 56: /* Stmt: "while" "(" Cond ")" Stmt  */
-#line 904 "./front/grammar.y"
+#line 904 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> \"while\" \"(\" Cond \")\" Stmt\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2233,11 +2233,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2237 "./front/grammar.tab.c"
+#line 2237 ".\\front\\grammar.tab.c"
     break;
 
   case 57: /* Stmt: "break" ";"  */
-#line 926 "./front/grammar.y"
+#line 926 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> \"break\" \";\"\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2250,11 +2250,11 @@ yyreduce:
       SetNodeType((yyval.asttreenode), AT_BreakStmt);
       SetLineno((yyval.asttreenode), LineNum);
     }
-#line 2254 "./front/grammar.tab.c"
+#line 2254 ".\\front\\grammar.tab.c"
     break;
 
   case 58: /* Stmt: "continue" ";"  */
-#line 939 "./front/grammar.y"
+#line 939 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> \"continue\" \";\"\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2267,11 +2267,11 @@ yyreduce:
       SetNodeType((yyval.asttreenode), AT_ContinueStmt);
       SetLineno((yyval.asttreenode), LineNum);
     }
-#line 2271 "./front/grammar.tab.c"
+#line 2271 ".\\front\\grammar.tab.c"
     break;
 
   case 59: /* Stmt: "return" ";"  */
-#line 952 "./front/grammar.y"
+#line 952 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> \"return\" \";\"\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2284,11 +2284,11 @@ yyreduce:
       SetNodeType((yyval.asttreenode), AT_ReturnStmt);
       SetLineno((yyval.asttreenode), LineNum);
     }
-#line 2288 "./front/grammar.tab.c"
+#line 2288 ".\\front\\grammar.tab.c"
     break;
 
   case 60: /* Stmt: "return" Exp ";"  */
-#line 965 "./front/grammar.y"
+#line 965 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Stmt -> \"return\" Exp \";\"\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2306,30 +2306,30 @@ yyreduce:
       SetOriginalType((yyval.asttreenode), StmtK);
       SetLineno((yyval.asttreenode), LineNum);
     }
-#line 2310 "./front/grammar.tab.c"
+#line 2310 ".\\front\\grammar.tab.c"
     break;
 
   case 61: /* Exp: AddExp  */
-#line 987 "./front/grammar.y"
+#line 987 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Exp -> AddExp\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2319 "./front/grammar.tab.c"
+#line 2319 ".\\front\\grammar.tab.c"
     break;
 
   case 62: /* Cond: LOrExp  */
-#line 996 "./front/grammar.y"
+#line 996 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Cond -> LOrExp\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
       SetNodeType((yyval.asttreenode), AT_Condition);
     }
-#line 2329 "./front/grammar.tab.c"
+#line 2329 ".\\front\\grammar.tab.c"
     break;
 
   case 63: /* LVal: Ident ExpGroup  */
-#line 1006 "./front/grammar.y"
+#line 1006 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : LVal -> Ident ExpGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -2347,11 +2347,11 @@ yyreduce:
 //      **************************************************************************
       free((yyvsp[-1].asttreenode));
     }
-#line 2351 "./front/grammar.tab.c"
+#line 2351 ".\\front\\grammar.tab.c"
     break;
 
   case 64: /* Number: IntConst  */
-#line 1028 "./front/grammar.y"
+#line 1028 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Number -> IntConst\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2364,11 +2364,11 @@ yyreduce:
       SetBasicType((yyval.asttreenode), Integer);
       SetLiteralContent((yyval.asttreenode), &(yyvsp[0].integer), Integer);
     }
-#line 2368 "./front/grammar.tab.c"
+#line 2368 ".\\front\\grammar.tab.c"
     break;
 
   case 65: /* Number: floatConst  */
-#line 1041 "./front/grammar.y"
+#line 1041 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : Number -> floatConst\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2381,47 +2381,47 @@ yyreduce:
       SetBasicType((yyval.asttreenode), Float);
       SetLiteralContent((yyval.asttreenode), &(yyvsp[0].floatValue), Float);
     }
-#line 2385 "./front/grammar.tab.c"
+#line 2385 ".\\front\\grammar.tab.c"
     break;
 
   case 66: /* PrimaryExp: "(" Exp ")"  */
-#line 1058 "./front/grammar.y"
+#line 1058 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : PrimaryExp -> \"(\" Exp \")\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
     }
-#line 2394 "./front/grammar.tab.c"
+#line 2394 ".\\front\\grammar.tab.c"
     break;
 
   case 67: /* PrimaryExp: LVal  */
-#line 1063 "./front/grammar.y"
+#line 1063 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : PrimaryExp -> LVal\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2403 "./front/grammar.tab.c"
+#line 2403 ".\\front\\grammar.tab.c"
     break;
 
   case 68: /* PrimaryExp: Number  */
-#line 1068 "./front/grammar.y"
+#line 1068 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : PrimaryExp -> Number\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2412 "./front/grammar.tab.c"
+#line 2412 ".\\front\\grammar.tab.c"
     break;
 
   case 69: /* UnaryExp: PrimaryExp  */
-#line 1077 "./front/grammar.y"
+#line 1077 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : UnaryExp -> PrimaryExp\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2421 "./front/grammar.tab.c"
+#line 2421 ".\\front\\grammar.tab.c"
     break;
 
   case 70: /* UnaryExp: Ident "(" ")"  */
-#line 1082 "./front/grammar.y"
+#line 1082 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : UnaryExp -> Ident \"(\" \")\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-2].asttreenode);
@@ -2429,11 +2429,11 @@ yyreduce:
       SetNodeType((yyval.asttreenode), AT_FuncCall);
       Ast_SetFlag((yyval.asttreenode), FUNCCALL_SIGNATURE);
     }
-#line 2433 "./front/grammar.tab.c"
+#line 2433 ".\\front\\grammar.tab.c"
     break;
 
   case 71: /* UnaryExp: Ident "(" FuncRParams ")"  */
-#line 1090 "./front/grammar.y"
+#line 1090 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : UnaryExp -> Ident \"(\" FuncRParams \")\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-1].asttreenode);
@@ -2453,11 +2453,11 @@ yyreduce:
 //      **************************************************************************
       free((yyvsp[-3].asttreenode));
     }
-#line 2457 "./front/grammar.tab.c"
+#line 2457 ".\\front\\grammar.tab.c"
     break;
 
   case 72: /* UnaryExp: UnaryOp UnaryExp  */
-#line 1110 "./front/grammar.y"
+#line 1110 ".\\front\\grammar.y"
     {
       MyPrintf(("%d : UnaryExp -> UnaryOp UnaryExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2474,38 +2474,38 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2478 "./front/grammar.tab.c"
+#line 2478 ".\\front\\grammar.tab.c"
     break;
 
   case 73: /* UnaryOp: "+"  */
-#line 1131 "./front/grammar.y"
+#line 1131 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : UnaryOp -> \"+\"\n", ++nCount));
       (yyval.integer) = AST_UNARYOP_PLUS;
     }
-#line 2487 "./front/grammar.tab.c"
+#line 2487 ".\\front\\grammar.tab.c"
     break;
 
   case 74: /* UnaryOp: "-"  */
-#line 1136 "./front/grammar.y"
+#line 1136 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : UnaryOp -> \"-\"\n", ++nCount));
       (yyval.integer) = AST_UNARYOP_MINUS;
     }
-#line 2496 "./front/grammar.tab.c"
+#line 2496 ".\\front\\grammar.tab.c"
     break;
 
   case 75: /* UnaryOp: "!"  */
-#line 1141 "./front/grammar.y"
+#line 1141 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : UnaryOp -> \"!\"\n", ++nCount));
       (yyval.integer) = AST_UNARYOP_EXCLAIM;
     }
-#line 2505 "./front/grammar.tab.c"
+#line 2505 ".\\front\\grammar.tab.c"
     break;
 
   case 76: /* FuncRParams: Exp FuncRParamsGroup  */
-#line 1150 "./front/grammar.y"
+#line 1150 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncRParams -> Exp FuncRParamsGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -2516,11 +2516,11 @@ yyreduce:
         }
       SetNodeType((yyval.asttreenode), AT_FuncRParams);
     }
-#line 2520 "./front/grammar.tab.c"
+#line 2520 ".\\front\\grammar.tab.c"
     break;
 
   case 77: /* FuncRParamsGroup: "," Exp FuncRParamsGroup  */
-#line 1164 "./front/grammar.y"
+#line 1164 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncRParamsGroup -> \",\" Exp FuncRParamsGroup\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
@@ -2530,11 +2530,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2534 "./front/grammar.tab.c"
+#line 2534 ".\\front\\grammar.tab.c"
     break;
 
   case 78: /* FuncRParamsGroup: %empty  */
-#line 1174 "./front/grammar.y"
+#line 1174 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncRParamsGroup -> (null)\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2545,20 +2545,20 @@ yyreduce:
         }
       SetOriginalType((yyval.asttreenode),FuncRParamsK);
     }
-#line 2549 "./front/grammar.tab.c"
+#line 2549 ".\\front\\grammar.tab.c"
     break;
 
   case 79: /* MulExp: UnaryExp  */
-#line 1189 "./front/grammar.y"
+#line 1189 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : MulExp -> UnaryExp\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2558 "./front/grammar.tab.c"
+#line 2558 ".\\front\\grammar.tab.c"
     break;
 
   case 80: /* MulExp: MulExp "*" UnaryExp  */
-#line 1194 "./front/grammar.y"
+#line 1194 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : MulExp -> MulExp \"*\" UnaryExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2580,11 +2580,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2584 "./front/grammar.tab.c"
+#line 2584 ".\\front\\grammar.tab.c"
     break;
 
   case 81: /* MulExp: MulExp "/" UnaryExp  */
-#line 1216 "./front/grammar.y"
+#line 1216 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : MulExp -> MulExp \"/\" UnaryExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2606,11 +2606,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2610 "./front/grammar.tab.c"
+#line 2610 ".\\front\\grammar.tab.c"
     break;
 
   case 82: /* MulExp: MulExp "%" UnaryExp  */
-#line 1238 "./front/grammar.y"
+#line 1238 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : MulExp -> MulExp \"%\" UnaryExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2632,20 +2632,20 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2636 "./front/grammar.tab.c"
+#line 2636 ".\\front\\grammar.tab.c"
     break;
 
   case 83: /* AddExp: MulExp  */
-#line 1264 "./front/grammar.y"
+#line 1264 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : AddExp -> MulExp\n", ++nCount));
        (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2645 "./front/grammar.tab.c"
+#line 2645 ".\\front\\grammar.tab.c"
     break;
 
   case 84: /* AddExp: AddExp "+" MulExp  */
-#line 1269 "./front/grammar.y"
+#line 1269 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : AddExp -> AddExp \"+\" MulExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2667,11 +2667,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2671 "./front/grammar.tab.c"
+#line 2671 ".\\front\\grammar.tab.c"
     break;
 
   case 85: /* AddExp: AddExp "-" MulExp  */
-#line 1291 "./front/grammar.y"
+#line 1291 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : AddExp -> AddExp \"-\" MulExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2693,20 +2693,20 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2697 "./front/grammar.tab.c"
+#line 2697 ".\\front\\grammar.tab.c"
     break;
 
   case 86: /* RelExp: AddExp  */
-#line 1317 "./front/grammar.y"
+#line 1317 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : RelExp -> AddExp\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2706 "./front/grammar.tab.c"
+#line 2706 ".\\front\\grammar.tab.c"
     break;
 
   case 87: /* RelExp: RelExp "<" AddExp  */
-#line 1322 "./front/grammar.y"
+#line 1322 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : RelExp -> RelExp \"<\" AddExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2729,11 +2729,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2733 "./front/grammar.tab.c"
+#line 2733 ".\\front\\grammar.tab.c"
     break;
 
   case 88: /* RelExp: RelExp ">" AddExp  */
-#line 1345 "./front/grammar.y"
+#line 1345 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : RelExp -> RelExp \">\" AddExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2756,11 +2756,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2760 "./front/grammar.tab.c"
+#line 2760 ".\\front\\grammar.tab.c"
     break;
 
   case 89: /* RelExp: RelExp "<=" AddExp  */
-#line 1368 "./front/grammar.y"
+#line 1368 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : RelExp -> RelExp \"<=\" AddExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2783,11 +2783,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2787 "./front/grammar.tab.c"
+#line 2787 ".\\front\\grammar.tab.c"
     break;
 
   case 90: /* RelExp: RelExp ">=" AddExp  */
-#line 1391 "./front/grammar.y"
+#line 1391 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : RelExp -> RelExp \">=\" AddExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2810,20 +2810,20 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2814 "./front/grammar.tab.c"
+#line 2814 ".\\front\\grammar.tab.c"
     break;
 
   case 91: /* EqExp: RelExp  */
-#line 1418 "./front/grammar.y"
+#line 1418 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : EqExp -> RelExp\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2823 "./front/grammar.tab.c"
+#line 2823 ".\\front\\grammar.tab.c"
     break;
 
   case 92: /* EqExp: EqExp "==" RelExp  */
-#line 1423 "./front/grammar.y"
+#line 1423 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : EqExp -> EqExp \"==\" RelExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2846,11 +2846,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2850 "./front/grammar.tab.c"
+#line 2850 ".\\front\\grammar.tab.c"
     break;
 
   case 93: /* EqExp: EqExp "!=" RelExp  */
-#line 1446 "./front/grammar.y"
+#line 1446 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : EqExp -> EqExp \"!=\" RelExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2873,20 +2873,20 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2877 "./front/grammar.tab.c"
+#line 2877 ".\\front\\grammar.tab.c"
     break;
 
   case 94: /* LAndExp: EqExp  */
-#line 1473 "./front/grammar.y"
+#line 1473 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : LAndExp -> EqExp\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2886 "./front/grammar.tab.c"
+#line 2886 ".\\front\\grammar.tab.c"
     break;
 
   case 95: /* LAndExp: LAndExp "&&" EqExp  */
-#line 1478 "./front/grammar.y"
+#line 1478 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : LAndExp -> LAndExp \"&&\" EqExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2909,20 +2909,20 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2913 "./front/grammar.tab.c"
+#line 2913 ".\\front\\grammar.tab.c"
     break;
 
   case 96: /* LOrExp: LAndExp  */
-#line 1505 "./front/grammar.y"
+#line 1505 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : LOrExp -> LAndExp\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2922 "./front/grammar.tab.c"
+#line 2922 ".\\front\\grammar.tab.c"
     break;
 
   case 97: /* LOrExp: LOrExp "||" LAndExp  */
-#line 1510 "./front/grammar.y"
+#line 1510 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : LOrExp -> LOrExp \"||\" LAndExp\n", ++nCount));
       (yyval.asttreenode) = AllocNode();
@@ -2945,20 +2945,20 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2949 "./front/grammar.tab.c"
+#line 2949 ".\\front\\grammar.tab.c"
     break;
 
   case 98: /* ConstExp: AddExp  */
-#line 1537 "./front/grammar.y"
+#line 1537 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : ConstExp -> AddExp\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[0].asttreenode);
     }
-#line 2958 "./front/grammar.tab.c"
+#line 2958 ".\\front\\grammar.tab.c"
     break;
 
   case 99: /* FuncDecl: BType Ident "(" ")" ";"  */
-#line 1547 "./front/grammar.y"
+#line 1547 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncDef -> BType Ident \"(\" \")\" \";\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-3].asttreenode);
@@ -2979,11 +2979,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 2983 "./front/grammar.tab.c"
+#line 2983 ".\\front\\grammar.tab.c"
     break;
 
   case 100: /* FuncDecl: BType Ident "(" FuncFParams ")" ";"  */
-#line 1568 "./front/grammar.y"
+#line 1568 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncDef -> BType Ident \"(\" FuncFParams \")\" \";\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-4].asttreenode);
@@ -2996,11 +2996,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 3000 "./front/grammar.tab.c"
+#line 3000 ".\\front\\grammar.tab.c"
     break;
 
   case 101: /* FuncDecl: "void" Ident "(" ")" ";"  */
-#line 1581 "./front/grammar.y"
+#line 1581 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncDef -> \"void\" Ident \"(\" \")\" \";\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-3].asttreenode);
@@ -3021,11 +3021,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 3025 "./front/grammar.tab.c"
+#line 3025 ".\\front\\grammar.tab.c"
     break;
 
   case 102: /* FuncDecl: "void" Ident "(" FuncFParams ")" ";"  */
-#line 1602 "./front/grammar.y"
+#line 1602 ".\\front\\grammar.y"
     { 
       MyPrintf(("%d : FuncDef -> \"void\" Ident \"(\" FuncFParams \")\" \";\"\n", ++nCount));
       (yyval.asttreenode) = (yyvsp[-4].asttreenode);
@@ -3038,11 +3038,11 @@ yyreduce:
           MyExit(1);
         }
     }
-#line 3042 "./front/grammar.tab.c"
+#line 3042 ".\\front\\grammar.tab.c"
     break;
 
 
-#line 3046 "./front/grammar.tab.c"
+#line 3046 ".\\front\\grammar.tab.c"
 
       default: break;
     }
@@ -3235,6 +3235,6 @@ yyreturnlab:
   return yyresult;
 }
 
-#line 1616 "./front/grammar.y"
+#line 1616 ".\\front\\grammar.y"
 
 
diff --git a/front/lex.yy.c b/front/lex.yy.c
index 6f7615041d8925f602e0182804a9df61f159398c..0cba0fdbf78f0cf329efecdc266200698867e256 100644
--- a/front/lex.yy.c
+++ b/front/lex.yy.c
@@ -1,6 +1,6 @@
-#line 1 "./front/lex.yy.c"
+#line 1 ".\\front\\lex.yy.c"
 
-#line 3 "./front/lex.yy.c"
+#line 3 ".\\front\\lex.yy.c"
 
 #define  YY_INT_ALIGNED short int
 
@@ -536,16 +536,16 @@ int yy_flex_debug = 0;
 #define YY_MORE_ADJ 0
 #define YY_RESTORE_YY_MORE_OFFSET
 char *yytext;
-#line 1 "./front/lex.l"
-#line 2 "./front/lex.l"
+#line 1 ".\\front\\lex.l"
+#line 2 ".\\front\\lex.l"
 #define YY_NO_UNISTD_H
 #include "compiler.h"
 #include <stdio.h>
 #include <string.h>
 #include "grammar.tab.h"
-#line 546 "./front/lex.yy.c"
+#line 546 ".\\front\\lex.yy.c"
 
-#line 548 "./front/lex.yy.c"
+#line 548 ".\\front\\lex.yy.c"
 
 #define INITIAL 0
 #define COMMENT 1
@@ -764,12 +764,12 @@ YY_DECL
 		}
 
 	{
-#line 19 "./front/lex.l"
+#line 19 ".\\front\\lex.l"
 
 
-#line 22 "./front/lex.l"
+#line 22 ".\\front\\lex.l"
  
-#line 772 "./front/lex.yy.c"
+#line 772 ".\\front\\lex.yy.c"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -828,234 +828,234 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 23 "./front/lex.l"
+#line 23 ".\\front\\lex.l"
 {;}        //忽略空白符
 	YY_BREAK
 case 2:
 /* rule 2 can match eol */
 YY_RULE_SETUP
-#line 24 "./front/lex.l"
+#line 24 ".\\front\\lex.l"
 {LineNum = LineNum + 1;}    //匹配到换行符,行数+1
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 25 "./front/lex.l"
+#line 25 ".\\front\\lex.l"
 {return (L_INT);}
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 26 "./front/lex.l"
+#line 26 ".\\front\\lex.l"
 {return (L_FLOAT);}
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 27 "./front/lex.l"
+#line 27 ".\\front\\lex.l"
 {return (L_CONST);}
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 28 "./front/lex.l"
+#line 28 ".\\front\\lex.l"
 {return (L_VOID);}
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 29 "./front/lex.l"
+#line 29 ".\\front\\lex.l"
 {return (L_BREAK);}
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 30 "./front/lex.l"
+#line 30 ".\\front\\lex.l"
 {return (L_CONTINUE);}
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 31 "./front/lex.l"
+#line 31 ".\\front\\lex.l"
 {return (L_RETURN);}
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 32 "./front/lex.l"
+#line 32 ".\\front\\lex.l"
 {return (L_IF);}
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 33 "./front/lex.l"
+#line 33 ".\\front\\lex.l"
 {return (L_ELSE);}
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 34 "./front/lex.l"
+#line 34 ".\\front\\lex.l"
 {return (L_WHILE);}
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 35 "./front/lex.l"
+#line 35 ".\\front\\lex.l"
 {return (L_FOR);}
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 36 "./front/lex.l"
+#line 36 ".\\front\\lex.l"
 {return (L_LT);}
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 37 "./front/lex.l"
+#line 37 ".\\front\\lex.l"
 {return (L_LTEQ);}
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 38 "./front/lex.l"
+#line 38 ".\\front\\lex.l"
 {return (L_GT);}
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 39 "./front/lex.l"
+#line 39 ".\\front\\lex.l"
 {return (L_GTEQ);}
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 40 "./front/lex.l"
+#line 40 ".\\front\\lex.l"
 {return (L_EQUALS);}
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 41 "./front/lex.l"
+#line 41 ".\\front\\lex.l"
 {return (L_NOTEQ);}
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 42 "./front/lex.l"
+#line 42 ".\\front\\lex.l"
 {return (L_ASSIGN);}
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 43 "./front/lex.l"
+#line 43 ".\\front\\lex.l"
 {return (L_PLUS);}
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 44 "./front/lex.l"
+#line 44 ".\\front\\lex.l"
 {return (L_MINUS);}
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 45 "./front/lex.l"
+#line 45 ".\\front\\lex.l"
 {return (L_MULT);}
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 46 "./front/lex.l"
+#line 46 ".\\front\\lex.l"
 {return (L_DIV);}
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 47 "./front/lex.l"
+#line 47 ".\\front\\lex.l"
 {return (L_MOD);}
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 48 "./front/lex.l"
+#line 48 ".\\front\\lex.l"
 {return (L_EXCLAIM);}
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 49 "./front/lex.l"
+#line 49 ".\\front\\lex.l"
 {return (L_ANDAND);}
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 50 "./front/lex.l"
+#line 50 ".\\front\\lex.l"
 {return (L_OROR);}
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 51 "./front/lex.l"
+#line 51 ".\\front\\lex.l"
 {return (L_SEMI);}
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 52 "./front/lex.l"
+#line 52 ".\\front\\lex.l"
 {return (L_COLON);}
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 53 "./front/lex.l"
+#line 53 ".\\front\\lex.l"
 {return (L_COMMA);}
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 54 "./front/lex.l"
+#line 54 ".\\front\\lex.l"
 {return (L_LPAREN);}
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 55 "./front/lex.l"
+#line 55 ".\\front\\lex.l"
 {return (L_RPAREN);}
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 56 "./front/lex.l"
+#line 56 ".\\front\\lex.l"
 {return (L_LCURLY);}
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 57 "./front/lex.l"
+#line 57 ".\\front\\lex.l"
 {return (L_RCURLY);}
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 58 "./front/lex.l"
+#line 58 ".\\front\\lex.l"
 {return (L_LBRACK);}
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 59 "./front/lex.l"
+#line 59 ".\\front\\lex.l"
 {return (L_RBRACK);}
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 61 "./front/lex.l"
+#line 61 ".\\front\\lex.l"
 {BEGIN(COMMENT);}
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 62 "./front/lex.l"
+#line 62 ".\\front\\lex.l"
 {BEGIN(INITIAL);}
 	YY_BREAK
 case 40:
 /* rule 40 can match eol */
 YY_RULE_SETUP
-#line 63 "./front/lex.l"
+#line 63 ".\\front\\lex.l"
 {LineNum++;}
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 64 "./front/lex.l"
+#line 64 ".\\front\\lex.l"
 {;}
 	YY_BREAK
 case YY_STATE_EOF(COMMENT):
-#line 65 "./front/lex.l"
+#line 65 ".\\front\\lex.l"
 {printf("%d: Unterminated comment\n", LineNum); MyExit(1);}
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 67 "./front/lex.l"
+#line 67 ".\\front\\lex.l"
 {BEGIN(COMMENT_SINGLELINE);}
 	YY_BREAK
 case 43:
 /* rule 43 can match eol */
 YY_RULE_SETUP
-#line 68 "./front/lex.l"
+#line 68 ".\\front\\lex.l"
 {BEGIN(INITIAL);LineNum++;}
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 69 "./front/lex.l"
+#line 69 ".\\front\\lex.l"
 {;}
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 71 "./front/lex.l"
+#line 71 ".\\front\\lex.l"
 {
                                   yylval.integer = (int)strtol(yytext, NULL, 10);
                                   return (IntConst);
@@ -1063,7 +1063,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 76 "./front/lex.l"
+#line 76 ".\\front\\lex.l"
 {
                                   yylval.integer = (int)strtol(yytext, NULL, 8);
                                   return (IntConst);
@@ -1071,7 +1071,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 81 "./front/lex.l"
+#line 81 ".\\front\\lex.l"
 {
                                   yylval.integer = (int)strtol(yytext, NULL, 16);
                                   return (IntConst);
@@ -1079,7 +1079,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 86 "./front/lex.l"
+#line 86 ".\\front\\lex.l"
 {
                                   yylval.floatValue = (float)atof(yytext);
                                   return (floatConst);
@@ -1087,7 +1087,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 91 "./front/lex.l"
+#line 91 ".\\front\\lex.l"
 {
                                   yylval.floatValue = (float)atof(yytext);
                                   return (floatConst);
@@ -1095,7 +1095,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 96 "./front/lex.l"
+#line 96 ".\\front\\lex.l"
 {
                                   yylval.asttreenode = AllocNode();
                                   if( yylval.asttreenode == NULL )
@@ -1115,10 +1115,10 @@ YY_RULE_SETUP
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 113 "./front/lex.l"
+#line 113 ".\\front\\lex.l"
 ECHO;
 	YY_BREAK
-#line 1121 "./front/lex.yy.c"
+#line 1121 ".\\front\\lex.yy.c"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(COMMENT_SINGLELINE):
 	yyterminate();
@@ -2124,7 +2124,7 @@ void yyfree (void * ptr )
 
 #define YYTABLES_NAME "yytables"
 
-#line 113 "./front/lex.l"
+#line 113 ".\\front\\lex.l"
 
 int yywrap(){    //文件结束处理函数,如果返回值为1就停止解析。可以用来解析多个文件。
     return 1;
diff --git a/front/main.c b/front/main.c
index b61f0aca4a650a48a430c8e6e6fe8ba415ee2682..38efad81b6f69928016068c0fb24a142b53f6781 100644
--- a/front/main.c
+++ b/front/main.c
@@ -181,21 +181,32 @@ main(
             goto label1;
             }
 
-#if defined( WITH_OUTPUTCFG )
-        if (!OutputCFG("testcase.pdf", &g_cfg, 0))
+        if (!BuildPrunedSSA(&g_cfg))
             {
             goto label1;
             }
-#endif
-
-        if (!BuildPrunedSSA(&g_cfg))
+            
+#if defined( WITH_OUTPUTCFG )
+        if (!OutputCFG("testcase.pdf", &g_cfg, 0))
             {
             goto label1;
             }
-            
+#endif
         if (g_Options.optimize > 0)
             { // 有优化
 
+            if (!PropagateConstant(&g_cfg, &g_symtab))
+                {
+                goto label1;
+                }
+
+#if defined( WITH_OUTPUTCFG )
+            if (!OutputCFG("testcase_1.pdf", &g_cfg, 0))
+                {
+                goto label1;
+                }
+#endif
+
 #if defined( WITH_LOCAL_VALUE_NUMBER )
             if (!Local_Value_Number(&g_cfg))
                 {
@@ -326,7 +337,7 @@ static int ValidOptions(char *argv[], int argc) {
     g_Options = default_options;
 
     for( i=1; i<argc; i++ ) {
-        if( (argv[i][0] == '-') /*|| (argv[i][0] == '/')*/ ) {
+        if( argv[i][0] == '-' /*|| (argv[i][0] == '/')*/ ) {
             switch( argv[i][1] ) {
             case 'v' :
                 g_Options.bVerbose = 1;
diff --git a/front/symtab.c b/front/symtab.c
index 41e0a89954f73a320e4db9ca2c91f13a0a12c884..71bd26c67fd632ef3e02664f3104b803bd82bede 100644
--- a/front/symtab.c
+++ b/front/symtab.c
@@ -1267,7 +1267,7 @@ int SymGetInitValueArray(SYMENT *psyment, int iIndex, void *lpValue)
             }
         else
             {
-            if (psyment->BasicType == Float)
+            if (psyment->BasicType == Integer)
                 {
                 *(int *)lpValue = result->integer_value;
                 }
@@ -1889,3 +1889,13 @@ PDYNAMIC_ARRAY SymGetDefInfo(SYMENT* psyment)
 {
     return &psyment->defs;
 }
+
+void SymSetPointTo(SYMENT* psyment, SYMENT* pointTo)
+{
+    psyment->pointTo = pointTo;
+}
+
+SYMENT* SymGetPointTo(SYMENT* psyment)
+{
+    return psyment->pointTo;
+}
diff --git a/include/backend.h b/include/backend.h
index 9f03b1dae21c87fe9aa908f0103cf35702495d75..7cfe12ce59f481277d58f72816de87ce775a71e4 100644
--- a/include/backend.h
+++ b/include/backend.h
@@ -27,12 +27,6 @@ typedef enum
     opmov,        /* 数据传送指令     mov */
     opldr,        /* 数据传送指令     ldr */
     opstr,        /* 数据传送指令     str */
-    opmoveq,      /* 数据传送指令     moveq */
-    opmovne,      /* 数据传送指令     movne */
-    opmovle,      /* 数据传送指令     movle */
-    opmovgt,      /* 数据传送指令     movgt */
-    opmovlt,      /* 数据传送指令     movlt */
-    opmovge,      /* 数据传送指令     movge */
     opvmrs,       /* 数据传送指令     vmrs */
     opvmov,       /* 数据传送指令     vmov */
     opvldr32,     /* 数据传送指令     vldr.32 */
@@ -65,12 +59,6 @@ typedef enum
     opvcmpef32,   /* 浮点数比较指令     vcmpe.f32 */
                   /* 跳转指令 */
     opbx,         /* 跳转指令     间接跳转 */
-    opbeq,        /* 跳转指令     beq */
-    opbne,        /* 跳转指令     bne */
-    opblt,        /* 跳转指令     blt */
-    opble,        /* 跳转指令     ble */
-    opbgt,        /* 跳转指令     bgt */
-    opbge,        /* 跳转指令     bge */
     opb,          /* 跳转指令     goto */
     opbl,         /* 跳转指令     函数调用 */
                   /* 函数调用相关指令 */
@@ -86,6 +74,28 @@ typedef enum
     opDBG,        /* 伪指令     调试 */
 } OPCODE;
 
+typedef enum condition_code condition_code;
+
+enum condition_code  {
+  CONDITION_AL,		/* Always (this is the default) */
+  CONDITION_EQ,		/* Equal */
+  CONDITION_NE,		/* Not equal */
+  CONDITION_CS,		/* Carry set (identical to HS) */
+  CONDITION_HS,		/* Unsigned higher or same (identical to CS) */
+  CONDITION_CC,		/* Carry clear (identical to LO) */
+  CONDITION_LO,		/* Unsigned lower (identical to CC) */
+  CONDITION_MI,		/* Minus or negative result */
+  CONDITION_PL,		/* Positive or zero result */
+  CONDITION_VS,		/* Overflow */
+  CONDITION_VC,		/* No overflow */
+  CONDITION_HI,		/* Unsigned higher */
+  CONDITION_LS,		/* Unsigned lower or same */
+  CONDITION_GE,		/* Signed greater than or equal */
+  CONDITION_LT,		/* Signed less than */
+  CONDITION_GT,		/* Signed greater than */
+  CONDITION_LE,		/* Signed less than or equal */
+  };
+  
 struct    argType {
     int     argType;
     union   {
@@ -137,6 +147,8 @@ typedef struct argType ARG;
 typedef struct {
       unsigned long identifier; // 标识符
       OPCODE iop  ;
+      condition_code cond;
+      int suffix;
       int nargs;
       ARG Args[1]  ;
    } INSTRUCTION;
@@ -202,7 +214,7 @@ int addasmInstrsub(PLLI instructions, int dest, int src1, int src2);
 int addasmInstrsubi(PLLI instructions, PDYNAMIC_ARRAY virtregs, int dest, int src1, int src2, int isuncertain);
 int addasmInstrsize(PLLI instructions, SYMENT *psyment, void *pValue, int fIsNum);
 int addasmInstrbx(PLLI instructions, int reg);
-int addasmInstrbranches(PLLI instructions, OPCODE iop, unsigned long destination);
+int addasmInstrbranches(PLLI instructions, condition_code iop, unsigned long destination);
 int addasmInstrmovv2p(PLLI instructions, int dest, PVIRTREGINFO src);
 int addasmInstrbl(PLLI instructions, SYMENT *psyment);
 int addasmInstrstr(PLLI instructions, int idregister, int iOffset);
diff --git a/include/dataflow.h b/include/dataflow.h
index 8aa659a03ac5aa20cde707f9da42f0156eef30cf..3de8a8038176969f5622cbb04de9616d5fe63a2e 100644
--- a/include/dataflow.h
+++ b/include/dataflow.h
@@ -36,5 +36,6 @@ typedef EXPRESSION *LPEXPRESSION;
 
 int DataflowAnalysis(control_flow_graph *cfg);
 void PrintLive(FILE *fileOutput, control_flow_graph *cfg);
+void Printdefuse(FILE *fileOutput, control_flow_graph *cfg);
 
 #endif // !defined(DATAFLOW_H)
diff --git a/include/frontend.h b/include/frontend.h
index e99f868505c41e4233e95daa06a9784fa28a7df3..498cbd44a07044347466eb6b802c0e5a46fc8a29 100644
--- a/include/frontend.h
+++ b/include/frontend.h
@@ -82,6 +82,7 @@ typedef struct _syment
     ValueType type;
     ExpType BasicType; // 'void' | 'int' | 'float'
     int IsPointer; // 是否是指针类型
+    struct _syment* pointTo; // 若是指针类型,它指向什么?
     long offset; /* 相对地址 */
     long width; /* 类型的宽度 */
     int isConst; /* 是否是常量 */
@@ -205,9 +206,9 @@ typedef struct df_ref df_ref;
 
 struct df_ref
 {
-    IRINSTRUCTION *insn;
-    int count;
-    int iArgIndex;
+    IRINSTRUCTION *insn; // 中间指令
+    int count; // SSA名字的数字
+    int iArgIndex; // 它在三地址代码中的位置
 };
 
 /* from IRInst.c */
@@ -217,7 +218,7 @@ struct df_ref
 typedef enum {
    IRINST_OP_MAX,    /* 最大指令码,也是无效指令 */
 
-   IRINST_OP_PLUS,      /* 加法指令,二元运算 ;约定:如果操作数1是数组,则相加结果是指针类型 */
+   IRINST_OP_PLUS,      /* 加法指令,二元运算 ;约定:如果操作数1是数组,则相加结果是指针类型,对数组既定值又使用。 */
    IRINST_OP_MULT,     /* 乘法指令,二元运算 */
    IRINST_OP_MINUS,     /* 减法指令,二元运算 */
    IRINST_OP_DIV,     /* 除法指令,二元运算 */
@@ -235,7 +236,7 @@ typedef enum {
    IRINST_OP_ARRAYASSIGN,    /* x[i]=y x<-Update(x, i,y)*/
 
    IRINST_OP_ASSIGN,    /* 复制指令,一元运算 */
-   IRINST_OP_PARAM,    /* 参数传递 */
+   IRINST_OP_PARAM,    /* 参数传递,会对数组定值 */
                        /* 注意:参数被放在arg1中,因为参数有可能是一个字面量 */
    IRINST_OP_GOTO,    /* 跳转指令 */
    IRINST_OP_RETURN,    /* 返回指令 */
@@ -245,7 +246,7 @@ typedef enum {
    IRINST_UNARYOP_MINUS, /* 单目运算符- */
    IRINST_UNARYOP_EXCLAIM, /* 单目运算符! */
 
-   IRINST_OP_ENTRY,   /* 函数入口指令 */
+   IRINST_OP_ENTRY,   /* 函数入口指令,会对所有参数定值 */
    IRINST_OP_EXIT,   /* 函数出口指令 */
 
    IRINST_OP_ITR,   /* 整数转换成实数 */
@@ -603,6 +604,8 @@ int SymIsPure(SYMENT* psyment);
 void SymSetIsPure(SYMENT* psyment, int IsPure);
 PDYNAMIC_ARRAY SymGetDefInfo(SYMENT* psyment);
 PDYNAMIC_ARRAY SymGetUseInfo(SYMENT* psyment);
+SYMENT* SymGetPointTo(SYMENT* psyment);
+void SymSetPointTo(SYMENT* psyment, SYMENT* pointTo);
 
 /* from IRInst.c */
 IRINSTRUCTION *addInst(InterCode *code, InterCode *g_code, unsigned long *labelCount, IRInstOperator iop, void *iarg1, void *iarg2, void *iarg3);
@@ -641,6 +644,8 @@ void   ir_SetMark(IRINSTRUCTION* inst, int bMark);
 void   ir_SetContainer(IRINSTRUCTION* inst, void * bb);
 void * ir_GetContainer(IRINSTRUCTION* inst);
 void swap_operands(InterCode *g_code);
+SYMENT* FinddefinedArray(IRINSTRUCTION* insn);
+IRINSTRUCTION* FindParamFunc(IRINSTRUCTION* insn);
 
 #if defined( WITH_PRINTIR_NEW )
 int PrintIr_New(FILE *stream, InterCode *g_code, SYMTAB *SymTable);
diff --git a/include/grammar.tab.h b/include/grammar.tab.h
index 5f02f1135784188640ff90eb4662042a3289da72..da309c6c5eaada4a82162b54d51cf8e122132cdf 100644
--- a/include/grammar.tab.h
+++ b/include/grammar.tab.h
@@ -121,13 +121,13 @@ extern int yydebug;
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 union YYSTYPE
 {
-#line 22 "./front/grammar.y"
+#line 22 ".\\front\\grammar.y"
 
         float     floatValue;
         int       integer;
         TreeNode* asttreenode;
 
-#line 131 "./include/grammar.tab.h"
+#line 131 ".\\include\\grammar.tab.h"
 
 };
 typedef union YYSTYPE YYSTYPE;
diff --git a/include/ssa.h b/include/ssa.h
index 399a19ffe535cc14fd53466f5e83d0d1f15b4758..fc8305aeae6cc90a80103b6824cdb26dd3a7f484 100644
--- a/include/ssa.h
+++ b/include/ssa.h
@@ -22,6 +22,8 @@ int Local_Value_Number(control_flow_graph* graph);
 int run_dce(control_flow_graph* graph);
 #endif
 
+int PropagateConstant(control_flow_graph* graph, SYMTAB *g_symtab);
+
 void phi_set_arg (phi *phi, unsigned index, SYMENT * phiarg, int iNumber);
 phi_arg_d *phi_arg (phi *phi_stmt, unsigned index);
 int phi_num_args (phi *phi_stmt);
diff --git a/optimize/cfg.c b/optimize/cfg.c
index 39e9f5de2eafa415fb209e81b7aca54705103c3b..ce3efd425fe88741aa1dd41fdea51f3dbcfebb26 100644
--- a/optimize/cfg.c
+++ b/optimize/cfg.c
@@ -361,6 +361,7 @@ void cfg_fast_deleteinst(control_flow_graph* graph, basic_block *bb, LIST_ITERAT
 	else
 		{
 		ir_SetOp(List_Current(iterator), IRINST_NOP);
+        List_Next(iterator);
         fNeedPatch = 0;
 		}
 
@@ -519,7 +520,7 @@ int OutputCFG(char *lpszFilename, control_flow_graph *cfg, int bReverse)
         fprintf( fp, "    struct%lu [label=\"B%lu | " ,bb_GetIdent(bb), bb_GetIdent(bb) );
 
         instructions = bb_GetInsts(bb);
-        if (iCount < 90)
+        if (iCount <= 162)
             {
             number =0;
             List_TRAVERSE(instructions, pvisit, &iterator)
diff --git a/optimize/dataflow.c b/optimize/dataflow.c
index 96ad137582b93bfadd1e2d8873f63e07888a3a8d..4a64ec5aea54a1d1e7d837e9a4efdcd01aaadb1a 100644
--- a/optimize/dataflow.c
+++ b/optimize/dataflow.c
@@ -127,10 +127,83 @@ void PrintLive(FILE *fileOutput, control_flow_graph *cfg)
        }
 }
 
-static int GetDefUses(control_flow_graph *cfg)
+void Printdefuse(FILE *fileOutput, control_flow_graph *cfg)
 {
     int inumber ; // 基本块数
     int i;
+    int count;
+    basic_block *bb;
+    CAVLTreeCursor c;
+    LPUDINFO lpUDData;
+    static const int max_nums_on_line = 10;
+
+    inumber = cfg_GetBlockNumber(cfg);
+    for (i = 0; i < inumber; i++)
+        {
+        bb = DynamicArrayRetrieve(&cfg->bbs, i);
+        fprintf (fileOutput, "  %s %lu:", "  livedef:", bb_GetIdent(bb));
+        count = max_nums_on_line + 1;
+        for (CAVLTreeSetCursor(bb_GetLiveVariablesDef(bb), POINT_TO_SMALLEST, &c, (void**)&lpUDData); lpUDData; CAVLTreeGetNext(&c, (void**)&lpUDData))
+            {
+            if (count > max_nums_on_line)
+                {
+                fprintf (fileOutput, "\n    ");
+                count = 0;
+                }
+            fprintf (fileOutput, " ");
+            PrintSymbol(fileOutput, lpUDData->lpBase);
+            if (lpUDData->IsArray)
+                {
+                fprintf(fileOutput, "[");
+                if (lpUDData->IsInteger)
+                    {
+                    fprintf(fileOutput, "%d", lpUDData->iOffset);
+                    }
+                else 
+                    {
+                    PrintSymbol(fileOutput, lpUDData->poffset);
+                    }
+                fprintf(fileOutput, "]");
+                }
+            count++;
+            }
+        fprintf (fileOutput, "\n\n");
+
+        fprintf (fileOutput, "  %s %lu:", "  liveuse:", bb_GetIdent(bb));
+        count = max_nums_on_line + 1;
+        for (CAVLTreeSetCursor(bb_GetLiveVariablesUse(bb), POINT_TO_SMALLEST, &c, (void**)&lpUDData); lpUDData; CAVLTreeGetNext(&c, (void**)&lpUDData))
+            {
+            if (count > max_nums_on_line)
+                {
+                fprintf (fileOutput, "\n    ");
+                count = 0;
+                }
+            fprintf (fileOutput, " ");
+            PrintSymbol(fileOutput, lpUDData->lpBase);
+            if (lpUDData->IsArray)
+                {
+                fprintf(fileOutput, "[");
+                if (lpUDData->IsInteger)
+                    {
+                    fprintf(fileOutput, "%d", lpUDData->iOffset);
+                    }
+                else 
+                    {
+                    PrintSymbol(fileOutput, lpUDData->poffset);
+                    }
+                fprintf(fileOutput, "]");
+                }
+            count++;
+            }
+        fprintf (fileOutput, "\n\n");
+
+       }
+}
+
+static int GetDefUses(control_flow_graph *cfg)
+{
+    int inumber ; // 基本块数
+    int i, j;
     PLLI instructions;
     //int nInstr ; 
     IRInstOperator iop;
@@ -152,6 +225,8 @@ static int GetDefUses(control_flow_graph *cfg)
     ExpType type;
     int ret = 0;
     LIST_ITERATOR iterator;
+    DOPEVECT *expdope;
+    PDYNAMIC_ARRAY FieldsDopeVector;
 
     inumber = cfg_GetBlockNumber(cfg);
     for (i = 0; i < inumber; i++)
@@ -192,7 +267,7 @@ static int GetDefUses(control_flow_graph *cfg)
                 { // 二元运算符
                 if ((!ir_IsArgFloat(currentinstruction, 1)) && (!ir_IsArgInteger(currentinstruction, 1)))
                     {// 处理第一操作数
-                    if (!SymIsConst(iarg1, NULL, NULL) || DynamicArrayGetCount(Get_Dope(iarg1)))
+                    if (!SymIsConst(iarg1, NULL, NULL) && !DynamicArrayGetCount(Get_Dope(iarg1)))
                         { 
                         memset ( &DummyData, 0, sizeof (DummyData));
                         DummyData.lpBase = iarg1;
@@ -524,22 +599,118 @@ static int GetDefUses(control_flow_graph *cfg)
                 if (CAVLTreeFindNode(use, &DummyData) == NULL)
                     {
                     needAlloc = 0;
-                    if ( ! (lpUDData = CAVLTreeFindNode(def, &DummyData))) {
+                    if ( ! (lpUDData = CAVLTreeFindNode(def, &DummyData))) 
+                        {
                         needAlloc = 1;
-                    }
-                    if ( needAlloc && !(lpUDData = AllocUDData())) {
+                        }
+                    if ( needAlloc && !(lpUDData = AllocUDData())) 
+                        {
                         return 0;
-                    }
-                    if ( needAlloc) {
+                        }
+                    if ( needAlloc) 
+                        {
                         lpUDData->lpBase = iarg3;
-                    }
+                        }
                     
-                    if ( needAlloc && !CAVLTreeAddNode(def, lpUDData, NULL)) {
+                    if ( needAlloc && !CAVLTreeAddNode(def, lpUDData, NULL)) 
+                        {
                         FreeUDData (lpUDData);
                         return 0;
+                        }
                     }
+
+                if (iop == IRINST_OP_PLUS && !ir_IsArgFloat(currentinstruction, 1) && !ir_IsArgInteger(currentinstruction, 1) &&
+                    !SymIsConst(iarg1, NULL, NULL) && DynamicArrayGetCount(Get_Dope(iarg1)))
+                    {
+                    memset ( &DummyData, 0, sizeof (DummyData));
+                    DummyData.lpBase = iarg1;
+
+                    if (CAVLTreeFindNode(use, &DummyData) == NULL)
+                        {
+                        needAlloc = 0;
+                        if ( ! (lpUDData = CAVLTreeFindNode(def, &DummyData))) 
+                            {
+                            needAlloc = 1;
+                            }
+                        if ( needAlloc && !(lpUDData = AllocUDData())) 
+                            {
+                            return 0;
+                            }
+                        if ( needAlloc) 
+                            {
+                            lpUDData->lpBase = iarg1;
+                            }
+                        
+                        if ( needAlloc && !CAVLTreeAddNode(def, lpUDData, NULL)) 
+                            {
+                            FreeUDData (lpUDData);
+                            return 0;
+                            }
+                        }
                     }
+                }
+            else if (iop == IRINST_OP_MEMSET)
+                {
+                if (!ir_IsArgFloat(currentinstruction, 1) && !ir_IsArgInteger(currentinstruction, 1) &&
+                    !SymIsConst(iarg1, NULL, NULL) && DynamicArrayGetCount(Get_Dope(iarg1)))
+                    {
+                    memset ( &DummyData, 0, sizeof (DummyData));
+                    DummyData.lpBase = iarg1;
+                    if (CAVLTreeFindNode(use, &DummyData) == NULL)
+                        {
+                        needAlloc = 0;
+                        if ( ! (lpUDData = CAVLTreeFindNode(def, &DummyData))) 
+                            {
+                            needAlloc = 1;
+                            }
+                        if ( needAlloc && !(lpUDData = AllocUDData())) 
+                            {
+                            return 0;
+                            }
+                        if ( needAlloc) 
+                            {
+                            lpUDData->lpBase = iarg1;
+                            }
 
+                        if ( needAlloc && !CAVLTreeAddNode(def, lpUDData, NULL)) 
+                            {
+                            FreeUDData (lpUDData);
+                            return 0;
+                            }
+                        }
+                    }
+                }
+            else if (iop == IRINST_OP_ENTRY)
+                {
+                FieldsDopeVector = Get_Dope(ir_GetArgVoidPtr(currentinstruction, 1));
+                for (j = (int)DynamicArrayGetCount(FieldsDopeVector) - 1; j>=0; j--)
+                    {
+                    expdope = DynamicArrayRetrieve(FieldsDopeVector, j);
+                    memset ( &DummyData, 0, sizeof (DummyData));
+                    DummyData.lpBase = expdope->psyment;
+                    if (DummyData.lpBase != NULL && CAVLTreeFindNode(use, &DummyData) == NULL)
+                        {
+                        needAlloc = 0;
+                        if ( ! (lpUDData = CAVLTreeFindNode(def, &DummyData))) 
+                            {
+                            needAlloc = 1;
+                            }
+                        if ( needAlloc && !(lpUDData = AllocUDData())) 
+                            {
+                            return 0;
+                            }
+                        if ( needAlloc) 
+                            {
+                            lpUDData->lpBase = DummyData.lpBase;
+                            }
+
+                        if ( needAlloc && !CAVLTreeAddNode(def, lpUDData, NULL)) 
+                            {
+                            FreeUDData (lpUDData);
+                            return 0;
+                            }
+                        }
+                    }
                 }
     /*        else if (iop == IRINST_OP_ARRAYASSIGN)
                 {
@@ -621,6 +792,9 @@ static int GetDefUses(control_flow_graph *cfg)
             }
 
         }
+
+    // Printdefuse(stdout, cfg);
+
     return 1;
 }
 
@@ -654,6 +828,7 @@ static int computeLiveness(control_flow_graph *cfg)
                     blkPtr = DynamicArrayRetrieve(&cfg->bbs, j); 
                     successor = bb_GetSuccessor(blkPtr);
                     nChildren = DynamicArrayGetCount(successor);
+                    FinalizeAVLTree(bb_GetLiveVariablesOut(blkPtr), NULL);
                     for (k = 0; k < nChildren; k++)
                         { // 遍历每个后继
                         lpChild = cfg_GetBlockByIdentifier(cfg, DynArrayItemAsLong(successor, k));
diff --git a/optimize/linklist.c b/optimize/linklist.c
index d125017af5d575b08ef7b851036a295cf7ed537b..ddad3824a5b0c700d70f21d40e0825037eb7709f 100644
--- a/optimize/linklist.c
+++ b/optimize/linklist.c
@@ -461,5 +461,12 @@ long List_Index( LIST_ITERATOR* pit )
 
 void *List_Current( LIST_ITERATOR* pit )
 {
-	return pit->_current->pValue;
+    if (pit->_current != NULL)
+        {
+        return (void*)pit->_current->pValue;
+        }
+    else 
+        {
+        return (void*)NULL;
+        }
 }
diff --git a/optimize/ssa.c b/optimize/ssa.c
index 2a6fb6162d311c8e7c30e777af38eb5b9f263082..dcb3d0a2c4aebfa5e3fc405fd21d052029456edf 100644
--- a/optimize/ssa.c
+++ b/optimize/ssa.c
@@ -1,3 +1,17 @@
+//+-------------------------------------------------------------------------
+//
+//  编译器
+//
+//  版权所有 (C) 苗潼超, 2023
+//
+//  文件:       ssa.c
+//
+//--------------------------------------------------------------------------
+
+// ssa.c : 静态单赋值及基于静态单赋值的优化
+//
+
+
 #include "compiler.h"
 
 static int CommCompare( long *arg1, long *arg2 )
@@ -10,6 +24,13 @@ static void destroy(void* p, void* T)
     free (p);
 }
 
+//############################################################################
+//############################################################################
+//
+//  静态单赋值
+//
+//############################################################################
+//############################################################################
 static int gendom(control_flow_graph* graph, int bReverse)
 {
     int iCount ;
@@ -352,6 +373,8 @@ static int Place_Phi_Functions(control_flow_graph* graph)
     LIST_ITERATOR iterator;
     bitmap_iterator bi;
     unsigned int ival;
+    DOPEVECT *expdope;
+    PDYNAMIC_ARRAY FieldsDopeVector;
 
     bSuccess = 0;
 
@@ -369,9 +392,23 @@ static int Place_Phi_Functions(control_flow_graph* graph)
     for (i = 0; i < iCount; i++) 
         {
         blkPtr = DynamicArrayRetrieve(&graph->bbs, i);
-        //printf("\nB%d: ", blkPtr->identifier);
+        // printf("\nB%d: ", blkPtr->identifier);
         insts = bb_GetInsts(blkPtr);
-        //nInstr = LinkListGetCount(insts);
+        if (bb_IsEntryBlock(blkPtr))
+            { // ENTRY块对参数定值。
+            FieldsDopeVector = Get_Dope(ir_GetArgVoidPtr(List_First(insts, &iterator), 1));
+            k = DynamicArrayGetCount(FieldsDopeVector);
+            for (j = 0; j < k; j++) 
+                {
+                expdope =DynamicArrayRetrieve(FieldsDopeVector, j);
+                if ( !CAVLTreeFindNode(bb_getaOrig(blkPtr), expdope->psyment) &&
+                    !CAVLTreeAddNode(bb_getaOrig(blkPtr), expdope->psyment, NULL) )
+                    {
+                    goto cleanup;
+                    }
+                }
+            }
+        
 
         List_TRAVERSE(insts, currentinstruction, &iterator)
         //for (j = 0; j < nInstr; j++)
@@ -384,7 +421,7 @@ static int Place_Phi_Functions(control_flow_graph* graph)
                     {
                     if ( k == 0 )
                         {
-                        psyment = ir_GetArgVoidPtr(currentinstruction, 1);
+                            psyment = ir_GetArgVoidPtr(currentinstruction, 1);
                         }
                     else if ( k == 1 )
                         {
@@ -394,13 +431,14 @@ static int Place_Phi_Functions(control_flow_graph* graph)
                         {
                         psyment = ir_GetDstVoidPtr(currentinstruction);
                         }//
-                    //printf("%d  ", psyment->iIdent);
+                    // printf("%d  ", psyment->iIdent);
+                    // PrintSymbol(stdout, psyment);
+                    // printf("\n");
                     if ( !CAVLTreeFindNode(bb_getaOrig(blkPtr), psyment) &&
                         !CAVLTreeAddNode(bb_getaOrig(blkPtr), psyment, NULL) )
                         {
                         goto cleanup;
                         }
-
                     }
                 }
             }
@@ -615,6 +653,8 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr)
     LIST_ITERATOR iterator;
     df_ref *def;
     df_ref *use;
+    DOPEVECT *expdope;
+    PDYNAMIC_ARRAY FieldsDopeVector;
 
     bSuccess = 0;
 
@@ -627,6 +667,33 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr)
     insts = bb_GetInsts(blkPtr);
     //nInstr = LinkListGetCount(insts);
 
+    if (bb_IsEntryBlock(blkPtr))
+        {
+        FieldsDopeVector = Get_Dope(ir_GetArgVoidPtr(List_First(insts, &iterator), 1));
+        k = DynamicArrayGetCount(FieldsDopeVector);
+        for (j = 0; j < k; j++) 
+            {
+            expdope =DynamicArrayRetrieve(FieldsDopeVector, j);
+            SymSetCount(expdope->psyment, SymGetCount(expdope->psyment)+1);
+            if ( !SymStackPush(expdope->psyment, SymGetCount(expdope->psyment)) )
+                {
+                goto cleanup;
+                }
+            if ((def = malloc (sizeof (*def))) == NULL)
+                {
+                goto cleanup;
+                }
+            def->count = SymGetStackTop(expdope->psyment);
+            def->insn = List_Current(&iterator);
+            def->iArgIndex = -1;
+            if (-1 ==DynamicArrayAdd(SymGetDefInfo(expdope->psyment), def))
+                {
+                free (def);
+                goto cleanup;
+                }
+            }
+        }
+
     List_TRAVERSE(insts, currentinstruction, &iterator)
     //for (j = 0; j < nInstr; j++)
         {
@@ -642,14 +709,24 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr)
                     !SymIsConst(psyment, NULL, NULL) &&
                     !SymIsFunction(psyment))
                     {
-                    ir_SetNumber(currentinstruction, 0, SymGetStackTop(psyment));
                     if ((use = malloc (sizeof (*use))) == NULL)
                         {
                         goto cleanup;
                         }
+
+                    if (iop==IRINST_OP_PLUS && DynamicArrayGetCount(Get_Dope(psyment)))
+                        {
+                        ir_SetNumber(currentinstruction, 3, SymGetStackTop(psyment));
+                        use->iArgIndex = 3;
+                        }
+                    else
+                        {
+                        ir_SetNumber(currentinstruction, 0, SymGetStackTop(psyment));
+                        use->iArgIndex = 0;
+                        }
                     use->count = SymGetStackTop(psyment);
                     use->insn = currentinstruction;
-                    use->iArgIndex = 0;
+                    
                     if (-1 ==DynamicArrayAdd(SymGetUseInfo(psyment), use))
                         {
                         free (use);
@@ -704,6 +781,7 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr)
                     }
                 }
             }
+
         for (k=0; k < 3 ;k++ )
             {
             if (ir_isDef(currentinstruction, k))
@@ -721,7 +799,7 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr)
                     psyment = ir_GetDstVoidPtr(currentinstruction);
                     }//
                 // printf("def : ");
-                // PrintSymbol(stdout, psyment);
+                // PrintInstruction(stdout, currentinstruction, 0, 1); PrintSymbol(stdout, psyment);
                 // printf("  %d\n", SymGetCount(psyment));
                 SymSetCount(psyment, SymGetCount(psyment)+1);
                 if ( !SymStackPush(psyment, SymGetCount(psyment)) )
@@ -744,6 +822,7 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr)
                 }
 
             } // for (k=0; k < 3 ;k++ )
+
         } // for (j = 0; j < nInstr; j++)
 
     successor = bb_GetSuccessor(blkPtr);
@@ -835,7 +914,7 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr)
                     }//
                 // printf("%d pop ", blkPtr->identifier);
                 // PrintSymbol(stdout, psyment);
-                
+                    
                 if (!SymStackPop(psyment))
                     {
                     internal_error(NULL, "Fatal error on line %u of %s.", __LINE__, __FILE__);
@@ -844,6 +923,7 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr)
                 // printf("  stacktop : %d\n", SymGetStackTop(psyment));
                 }
             }
+        
         }
 
     bSuccess = 1;
@@ -941,6 +1021,13 @@ void phi_set_arg (phi *phi, unsigned index, SYMENT * phiarg, int iNumber)
 }
 
 #if defined( WITH_LOCAL_VALUE_NUMBER )
+//############################################################################
+//############################################################################
+//
+//  局部值编号
+//
+//############################################################################
+//############################################################################
 static int
 cmp_Value_Number(EXPRESSION* a, EXPRESSION* b)
 {
@@ -1012,7 +1099,7 @@ cmp_Value_Number(EXPRESSION* a, EXPRESSION* b)
             return ret;
         }
 
-    if (IRINST_OP_ARRAYASSIGN != a->iop)
+    if (IRINST_OP_ARRAYASSIGN != a->iop && IRINST_OP_PLUS != a->iop)
         {
         return ret;
         }
@@ -1041,7 +1128,7 @@ cmp_hash(EXPRESSION* a, EXPRESSION* b)
     if (ret)
         return ret;
     ret = (a)->Value_Number[1] - (b)->Value_Number[1];
-    if (IRINST_OP_ARRAYASSIGN != a->iop)
+    if (IRINST_OP_ARRAYASSIGN != a->iop && IRINST_OP_PLUS != a->iop)
         {
         return ret;
         }
@@ -1177,10 +1264,11 @@ static int Value_Number(basic_block* bb)
                 expr2.Value_Number[1] = -1;
                 }
 
-            if (iop == IRINST_OP_ARRAYASSIGN)
+            if (iop == IRINST_OP_ARRAYASSIGN ||
+                (iop == IRINST_OP_PLUS && !ir_IsArgInteger(insn, 1) && !ir_IsArgFloat(insn, 1) && DynamicArrayGetCount(Get_Dope(ir_GetArgVoidPtr(insn, 1)))))
                 {
                 expr.arg1.symbol.num = ir_GetNumber(insn, 3);
-                ir_GetOperand(insn, 2, &Type, &isImmediate, &expr.arg1);
+                ir_GetOperand(insn, iop == IRINST_OP_PLUS ? 0 : 2, &Type, &isImmediate, &expr.arg1);
                 expr.fIsArg1Float = 0;
                 expr.fIsArg1Integer = 0;
                 expr.iop = IRINST_OP_MAX;
@@ -1322,6 +1410,13 @@ Cleanup:
 #endif
 
 #if defined( WITH_DCE )
+//############################################################################
+//############################################################################
+//
+//  死代码删除
+//
+//############################################################################
+//############################################################################
 /* 如果insn是可以通过死代码删除删除的普通指令,则返回true。  */
 static int
 deletable_insn(IRINSTRUCTION* insn)
@@ -1397,7 +1492,7 @@ prescan_insns_for_dce(control_flow_graph* graph, CAVLTree* worklist)
             if (!deletable_insn(insn))
                 {
                 ir_SetMark(insn, 1);
-                //printf("%d\n", insn->identifier);
+                // printf("%d\n", insn->identifier);
                 if (CAVLTreeAddNode(worklist, insn, NULL) == 0)
                     {
                     goto Cleanup;
@@ -1534,7 +1629,8 @@ mark_dependencies (control_flow_graph* graph, CAVLTree* worklist, IRINSTRUCTION
 	else if (iop != IRINST_OP_ENTRY && iop != IRINST_OP_EXIT)
 		{
         pSym = ir_GetArgVoidPtr(insn, 1);
-		if (!ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1) && pSym && !SymIsConst(pSym, NULL, NULL))
+		if (!ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1) && pSym && !SymIsConst(pSym, NULL, NULL) &&
+            !(iop==IRINST_OP_PLUS && DynamicArrayGetCount(Get_Dope(pSym))))
             {
             nCount = DynamicArrayGetCount(SymGetDefInfo(pSym));
             for (j = 0; j<nCount; j++)
@@ -1599,6 +1695,28 @@ mark_dependencies (control_flow_graph* graph, CAVLTree* worklist, IRINSTRUCTION
                 }
             }
 
+        pSym = ir_GetArgVoidPtr(insn, 1);
+		if (iop == IRINST_OP_PLUS && !ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1) && DynamicArrayGetCount(Get_Dope(pSym)))
+            {
+            nCount = DynamicArrayGetCount(SymGetDefInfo(pSym));
+            for (j = 0; j<nCount; j++)
+                {
+                def = DynamicArrayRetrieve(SymGetDefInfo(pSym), j);
+                if (def->count == ir_GetNumber(insn, 3))
+                    {
+                    if (!ir_GetMark(def->insn))
+                        {
+                        ir_SetMark(def->insn, 1);
+                        if (!CAVLTreeFindNode(worklist, def->insn) && !CAVLTreeAddNode(worklist, def->insn, NULL))
+                            {
+                            goto Cleanup;
+                            }
+                        }
+                    break;
+                    }
+                }
+            }
+
 		}
 
     bb = ir_GetContainer(insn);
@@ -1655,7 +1773,7 @@ static int dce (control_flow_graph* graph, CAVLTree* worklist)
         {
         insn = CAVLTreeGetIndexData(worklist, 0);
         CAVLTreeDelNodebyidx(worklist, 0);
-         //printf("%d  %d\n", CAVLTreeGetItemCount(worklist), insn->identifier);
+        // printf("%d  %d\n", CAVLTreeGetItemCount(worklist), insn->identifier);
         if (!mark_dependencies(graph, worklist, insn))
             {
             goto Cleanup;
@@ -1680,7 +1798,7 @@ delete_unmarked_insns (control_flow_graph* graph)
     IRINSTRUCTION* op;
     basic_block* p;
 
-    // int iCounter;
+    int iCounter;
 
     // fprintf(stdout, "\n");
     n = cfg_GetBlockNumber(graph);
@@ -1689,10 +1807,11 @@ delete_unmarked_insns (control_flow_graph* graph)
         bb = DynamicArrayRetrieve(&graph->bbs, i);
         instructions = bb_GetInsts(bb);
 
-        // iCounter = 0;
+        iCounter = 0;
 
-        List_TRAVERSE(instructions, insn, &iterator)
+        for(  insn=List_First(instructions, &iterator);List_Current(&iterator)!=NULL;)
             {
+            // printf("%d\n", insn->identifier);
             if (!ir_GetMark(insn))
                 {
                 iop = ir_getOp(insn);
@@ -1732,6 +1851,8 @@ delete_unmarked_insns (control_flow_graph* graph)
                         }
                     ir_SetOp(insn, IRINST_OP_GOTO);
                     ir_SetBranchTarget(insn, GetIdentifier(op));
+
+                    insn = List_Next(&iterator);
                     // fprintf(stdout, "  ->  ");
                     // PrintInstruction(stdout, insn, 0, 1);
                     // fprintf(stdout, "\n");
@@ -1740,11 +1861,17 @@ delete_unmarked_insns (control_flow_graph* graph)
                     {
                     // fprintf(stdout, "deleting B%d %d", bb_GetIdent(insn->bb), iCounter);
                     // PrintInstruction(stdout, insn, 0, 1);
+                    // fprintf(stdout, "\n");
                     cfg_fast_deleteinst(graph, bb, &iterator);
-                    List_Prev(&iterator);
+                    insn = List_Current(&iterator);
                     }
                 }
-            // iCounter++;
+            else
+                {
+                insn = List_Next(&iterator);
+                } 
+            
+            iCounter++;
             }
         }
 
@@ -1885,3 +2012,1123 @@ Cleanup:
     return bSuccess;
 }
 #endif
+
+typedef struct value_ent {
+    struct ssa_name ve_valuename;
+    union {
+        int integer_val;
+        float real_val;
+    }   ve_value;
+    int IsInteger;
+    int ve_type; // -1, 0, +1
+}VALENT, *PVALENT;
+
+static int
+cmp_value_ent (PVALENT a, PVALENT b)
+{
+    int ret;
+    if (a == b)
+        return 0;
+    ret = (int)SymGetIdentifier(a->ve_valuename.var) - (int)SymGetIdentifier(b->ve_valuename.var);
+    if (ret)
+        return ret;
+    return (a->ve_valuename.num -b->ve_valuename.num);
+}
+
+static int evaluate(CAVLTree *names, PVALENT value, IRINSTRUCTION *insn)
+{
+    int bSuccess = 0;
+    VALENT *       opr1;
+    VALENT *       opr2;
+    VALENT *       opr3;
+    VALENT dummy;
+    VALENT dummy1, dummy2, dummy3;
+    ExpType type;
+    SYMENT dummy4;
+    IRInstOperator iop  ;
+    phi_arg_d *lpArg;
+    int i, n;
+
+    memset (&dummy, 0, sizeof (dummy));
+    memset (&dummy1, 0, sizeof (dummy1));
+    memset (&dummy2, 0, sizeof (dummy2));
+    memset (&dummy3, 0, sizeof (dummy3));
+    memset (&dummy4, 0, sizeof (dummy4));
+
+    iop = ir_getOp(insn);
+
+	if (iop != IRINST_OP_PHI)
+		{
+        if (!ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1))
+            {
+            dummy.ve_valuename.var = ir_GetArgVoidPtr(insn, 1);
+            if (DynamicArrayGetCount(Get_Dope(dummy.ve_valuename.var)) != 0 && 
+                iop != IRINST_OP_ARRAYASSIGN && iop != IRINST_OP_ASSIGNARRAY)
+                {
+                goto dodefault;
+                }
+            if (DynamicArrayGetCount(Get_Dope(dummy.ve_valuename.var)) != 0 ||
+                !SymIsConst(dummy.ve_valuename.var, &type, &dummy.ve_value))
+                {
+                dummy.ve_valuename.num = ir_GetNumber(insn, 0);
+                dummy.ve_valuename.var = dummy.ve_valuename.var ? dummy.ve_valuename.var : &dummy4;
+                if (IsInFilescope(SymGetScope(dummy.ve_valuename.var)))
+                    {
+                    goto dodefault;
+                    }
+                if ( ! ( opr1 = CAVLTreeFindNode ( names, &dummy ) ) )
+                    { // 没找到,应该是一个全局变量。
+                    goto dodefault;
+                    }
+                }
+            else if (type == Integer)
+                {
+                dummy.IsInteger =1;
+                opr1 = &dummy;
+                dummy.ve_valuename.var = &dummy4;
+                }
+            else
+                {
+                dummy.ve_valuename.var = &dummy4;
+                opr1 = &dummy;
+                }
+            }
+        else if (ir_IsArgFloat(insn, 1))
+            {
+            dummy.ve_value.real_val = ir_GetArgFloat(insn, 1);
+            opr1 = &dummy;
+            dummy.ve_valuename.var = &dummy4;
+            }
+        else
+            {
+            dummy.ve_value.integer_val = ir_GetArgInteger(insn, 1);
+            dummy.IsInteger = 1;
+            opr1 = &dummy;
+            dummy.ve_valuename.var = &dummy4;
+            }
+		}
+
+    if (iop != IRINST_OP_ASSIGN &&
+        iop != IRINST_UNARYOP_PLUS &&
+        iop != IRINST_UNARYOP_MINUS &&
+        iop != IRINST_UNARYOP_EXCLAIM &&
+        iop != IRINST_OP_ITR &&
+        iop != IRINST_OP_RTI &&
+        iop != IRINST_OP_PHI &&
+        iop != IRINST_OP_PARAM)
+        {
+        if (!ir_IsArgFloat(insn, 0) && !ir_IsArgInteger(insn, 0))
+            {
+            dummy1.ve_valuename.var = ir_GetArgVoidPtr(insn, 0);
+            if (DynamicArrayGetCount(Get_Dope(dummy1.ve_valuename.var)) || !SymIsConst(dummy1.ve_valuename.var, NULL, NULL))
+                {
+                dummy1.ve_valuename.num = ir_GetNumber(insn, 1);
+                dummy1.ve_valuename.var = dummy1.ve_valuename.var ? dummy1.ve_valuename.var : &dummy4;
+                if (IsInFilescope(SymGetScope(dummy1.ve_valuename.var)))
+                    {
+                    goto dodefault;
+                    }
+                if ( ! ( opr2 = CAVLTreeFindNode ( names, &dummy1 ) ) )
+                    { // 没找到,应该是一个全局变量。
+                    goto dodefault;
+                    }
+                }
+            else
+                {
+                SymIsConst(dummy1.ve_valuename.var, &type, &dummy1.ve_value);
+                dummy1.ve_valuename.var = &dummy4;
+                opr2 = &dummy1;
+                if (type == Integer)
+                    {
+                    dummy1.IsInteger =1;
+                    }
+                }
+            }
+        else if (ir_IsArgFloat(insn, 0))
+            {
+            dummy1.ve_value.real_val = ir_GetArgFloat(insn, 0);
+            opr2 = &dummy1;
+            dummy1.ve_valuename.var = &dummy4;
+            }
+        else
+            {
+            dummy1.ve_value.integer_val = ir_GetArgInteger(insn, 0);
+            dummy1.IsInteger = 1;
+            opr2 = &dummy1;
+            dummy1.ve_valuename.var = &dummy4;
+            }
+        }
+
+	if (iop == IRINST_OP_ARRAYASSIGN)
+		{
+		dummy2.ve_valuename.var = ir_GetDstVoidPtr(insn);
+        dummy2.ve_valuename.num = ir_GetNumber(insn, 3);
+        if (IsInFilescope(SymGetScope(dummy2.ve_valuename.var)))
+            {
+            goto dodefault;
+            }
+        if ( ! ( opr3 = CAVLTreeFindNode ( names, &dummy2 ) ) )
+            { // 没找到,应该是一个全局变量。
+            goto dodefault;
+            }
+		}
+
+	switch ( ir_getOp(insn) )
+	{
+	case IRINST_OP_PLUS:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = opr1->ve_value.integer_val + opr2->ve_value.integer_val;
+                }
+            else 
+                {
+                value->IsInteger = 0;
+                value->ve_value.real_val = opr1->ve_value.real_val + opr2->ve_value.real_val;
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OP_MULT:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = opr1->ve_value.integer_val * opr2->ve_value.integer_val;
+                }
+            else 
+                {
+                value->IsInteger = 0;
+                value->ve_value.real_val = opr1->ve_value.real_val * opr2->ve_value.real_val;
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            if ((!opr1->ve_type && opr1->ve_value.integer_val == 0) ||
+                (!opr2->ve_type && opr2->ve_value.integer_val == 0))
+                {
+                value->IsInteger = opr1->IsInteger;
+                value->ve_value.integer_val = 0;
+                }
+            else
+                {
+                value->ve_type = -1;
+                }
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OP_MINUS:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = opr1->ve_value.integer_val - opr2->ve_value.integer_val;
+                }
+            else 
+                {
+                value->IsInteger = 0;
+                value->ve_value.real_val = opr1->ve_value.real_val - opr2->ve_value.real_val;
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OP_DIV:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->IsInteger)
+                {
+                if (opr2->ve_value.integer_val == 0)
+                    {
+                    value->ve_type = -1;
+                    }
+                else
+                    {
+                    value->IsInteger = 1;
+                    value->ve_value.integer_val = opr1->ve_value.integer_val / opr2->ve_value.integer_val;
+                    }
+                }
+            else 
+                {
+                value->IsInteger = 0;
+                value->ve_value.real_val = opr1->ve_value.real_val / opr2->ve_value.real_val;
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            if (opr2->ve_type == 0 && !opr2->IsInteger && opr2->ve_value.integer_val == 0)
+                {
+                value->IsInteger = 0;
+                value->ve_value.real_val = opr1->ve_value.real_val / opr2->ve_value.real_val;
+                }
+            else
+                {
+                value->ve_type = -1;
+                }
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OP_MOD:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->ve_value.integer_val == 0)
+                {
+                value->ve_type = -1;
+                }
+            else
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = opr1->ve_value.integer_val % opr2->ve_value.integer_val;
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OP_ASSIGN:
+	case IRINST_UNARYOP_PLUS:
+        if (!opr1->ve_type)
+            {
+            value->ve_type = 0;
+            value->IsInteger = opr1->IsInteger;
+            memcpy ( &value->ve_value, &opr1->ve_value, sizeof(opr1->ve_value) ) ;
+            }
+        else if (opr1->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_UNARYOP_MINUS:
+        if (!opr1->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr1->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = -opr1->ve_value.integer_val;
+                }
+            else
+                {
+                value->IsInteger = 0;
+                value->ve_value.real_val = -opr1->ve_value.real_val;
+                }
+            }
+        else if (opr1->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_UNARYOP_EXCLAIM:
+        if (!opr1->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr1->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = !opr1->ve_value.integer_val;
+                }
+            else
+                {
+                value->IsInteger = 1;
+                value->ve_value.real_val = !opr1->ve_value.real_val;
+                }
+            }
+        else if (opr1->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OPVALUE_EQUALS:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.integer_val == opr2->ve_value.integer_val);
+                }
+            else 
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.real_val == opr2->ve_value.real_val);
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OPVALUE_NOTEQ:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.integer_val != opr2->ve_value.integer_val);
+                }
+            else 
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.real_val != opr2->ve_value.real_val);
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OPVALUE_GT:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.integer_val > opr2->ve_value.integer_val);
+                }
+            else 
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.real_val > opr2->ve_value.real_val);
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OPVALUE_LT:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.integer_val < opr2->ve_value.integer_val);
+                }
+            else 
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.real_val < opr2->ve_value.real_val);
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OPVALUE_GTEQ:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.integer_val >= opr2->ve_value.integer_val);
+                }
+            else 
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.real_val >= opr2->ve_value.real_val);
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OPVALUE_LTEQ:
+        if (!opr1->ve_type && !opr2->ve_type)
+            {
+            value->ve_type = 0;
+            if (opr2->IsInteger)
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.integer_val <= opr2->ve_value.integer_val);
+                }
+            else 
+                {
+                value->IsInteger = 1;
+                value->ve_value.integer_val = (opr1->ve_value.real_val <= opr2->ve_value.real_val);
+                }
+            }
+        else if (opr1->ve_type==-1 || opr2->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+		break;
+	case IRINST_OP_ITR:
+        if (!opr1->ve_type)
+            {
+            value->ve_type = 0;
+            value->IsInteger = 0;
+            value->ve_value.real_val = (float)opr1->ve_value.integer_val;
+            }
+        else if (opr1->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+        break;
+	case IRINST_OP_RTI:
+        if (!opr1->ve_type)
+            {
+            value->ve_type = 0;
+            value->IsInteger = 1;
+            value->ve_value.integer_val = (int)opr1->ve_value.real_val;
+            }
+        else if (opr1->ve_type==-1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+        break;
+	case IRINST_OP_ARRAYASSIGN:
+        if (opr3->ve_type >= 0 && opr1->ve_type == 0 && opr2->ve_type == 0)
+            {
+            value->ve_type = 0;
+            SymIsConst(opr3->ve_valuename.var, &type, NULL);
+            if (!SymSetInitValueArray(opr3->ve_valuename.var, opr2->ve_value.integer_val / (opr3->IsInteger ? SIZE_INTEGER : SIZE_FLOAT), &opr1->ve_value))
+                {
+                return 0;
+                }
+            }
+        else if (opr3->ve_type == -1 || opr1->ve_type == -1 || opr2->ve_type == -1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+        break;
+	case IRINST_OP_ASSIGNARRAY:
+        if (opr1->ve_type == 0 && opr2->ve_type==0)
+            {
+		// TODO: 对数组越界的检查..
+            value->ve_type = 0;
+            SymIsConst(opr1->ve_valuename.var, &type, NULL);
+            value->IsInteger = (type==Integer);
+            if (!SymGetInitValueArray(opr1->ve_valuename.var, opr2->ve_value.integer_val / (type==Integer?SIZE_INTEGER:SIZE_FLOAT), &value->ve_value))
+                {
+                return 0;
+                }
+            }
+        else if (opr1->ve_type == -1 || opr2->ve_type == -1)
+            {
+            value->ve_type = -1;
+            }
+        else
+            {
+            value->ve_type = 1;
+            }
+        break;
+	case IRINST_OP_PHI:
+        n = phi_num_args(ir_GetArgVoidPtr(insn, 1));
+        for (i = 0; i < n; i++)
+            {
+            lpArg = phi_arg(ir_GetArgVoidPtr(insn, 1), i);
+            if (i == 0)
+                {
+                dummy.ve_valuename.num = lpArg->iNumber;
+                dummy.ve_valuename.var = lpArg->psyment;
+                if ( ! ( opr1 = CAVLTreeFindNode ( names, &dummy ) ) )
+                    { // 没找到,应该是一个全局变量。
+                    goto dodefault;
+                    }
+                value->IsInteger = opr1->IsInteger;
+                value->ve_type = opr1->ve_type;
+                memcpy ( &value->ve_value, &opr1->ve_value, sizeof(opr1->ve_value) ) ;
+                }
+            else
+                {
+                dummy.ve_valuename.num = lpArg->iNumber;
+                dummy.ve_valuename.var = lpArg->psyment;
+                if ( ! ( opr1 = CAVLTreeFindNode ( names, &dummy ) ) )
+                    { // 没找到,应该是一个全局变量。
+                    goto dodefault;
+                    }
+
+                if (!opr1->ve_type && !value->ve_type)
+                    {
+                    if (value->ve_value.integer_val != opr1->ve_value.integer_val)
+                        {
+                        value->ve_type = -1;
+                        }
+                    }
+                else if (opr1->ve_type==-1 || value->ve_type == -1)
+                    {
+                    value->ve_type = -1;
+                    break;
+                    }
+                // else if (opr1->ve_type==1 || value->ve_type == 1)
+                //     {
+                //     value->ve_type = 1;
+                //     break;
+                //     }
+                else if (value->ve_type==1)
+                    {
+                    value->IsInteger = opr1->IsInteger;
+                    value->ve_type = opr1->ve_type;
+                    memcpy ( &value->ve_value, &opr1->ve_value, sizeof(opr1->ve_value) ) ;
+                    }
+                }
+            }
+		break;
+dodefault:
+	default:
+        value->ve_type = -1;
+		break;
+    }
+
+// Success:
+    return 1;
+}
+
+int PropagateConstant(control_flow_graph* graph, SYMTAB *g_symtab)
+{
+    CAVLTree names;
+    CAVLTree worklist;
+    DYNAMIC_ARRAY MyQueue, tmpqueue;
+    int bSuccess = 0;
+    int i, n, j, k;
+    int iEdge;
+    SYMTAB *  pSymTable;
+    int nChildren = 0;
+    CAVLTreeCursor c;   
+    SYMENT *psyment;
+    PVALENT value;
+    PVALENT value2;
+    PDYNAMIC_ARRAY defs;
+    PDYNAMIC_ARRAY uses;
+    df_ref* def;
+    df_ref *use;
+    IRInstOperator iop  ;
+    ExpType type;
+    int isImmediate;
+    VALENT dummy;
+    VALENT saved;
+    basic_block *bb;
+    IRINSTRUCTION *insn;
+    LIST_ITERATOR iterator;
+    int nCount;
+    phi_arg_d *lpArg;
+    int bSkip;
+
+    InitializeAVLTree(&names, NULL, (NODECOMPAREPROC)cmp_value_ent, destroy);
+    InitializeAVLTree(&worklist, NULL, (NODECOMPAREPROC)cmp_value_ent, NULL);
+
+    DynamicArrayInit(&MyQueue, NULL);
+    DynamicArrayInit(&tmpqueue, NULL);
+    if( -1 == DynamicArrayAdd(&MyQueue, g_symtab))
+        {
+        goto Cleanup;    // sorry
+        }
+
+    while ( DynamicArrayGetCount(&MyQueue) )
+        {
+        DynamicArrayDestroy(&tmpqueue);
+        DynamicArrayInit(&tmpqueue, NULL);
+
+        n = (int)DynamicArrayGetCount(&MyQueue);
+        for ( i = 0; i < n; i++ )
+            {
+            if( -1 == DynamicArrayAdd(&tmpqueue, DynamicArrayRetrieve(&MyQueue, i)))
+                {
+                goto Cleanup;    // sorry
+                }
+            }
+        DynamicArrayDestroy(&MyQueue);
+        DynamicArrayInit(&MyQueue, NULL);
+
+        n = (int)DynamicArrayGetCount(&tmpqueue);
+        for ( iEdge = 0; iEdge < n; iEdge++ )
+            {
+            pSymTable = DynamicArrayRetrieve(&tmpqueue, iEdge);
+            // 把它的孩子都加入队列。
+            nChildren = (int)DynamicArrayGetCount(&pSymTable->rgsymtab);
+            for ( j = 0; j < nChildren; j++ )
+                {
+                if( -1 == DynamicArrayAdd(&MyQueue, DynamicArrayRetrieve(&pSymTable->rgsymtab, j)))
+                    {
+                    goto Cleanup;    // sorry
+                    }
+                }
+            for ( CAVLTreeSetCursor(&pSymTable->rgsyment, POINT_TO_SMALLEST, &c, (void**)&psyment); psyment; CAVLTreeGetNext(&c, (void**)&psyment) )
+                {
+                if (SymIsConst(psyment, NULL, NULL) && DynamicArrayGetCount(Get_Dope(psyment)))
+                    { // 常量数组(一定位于全局)
+                    if ( ! ( value = malloc ( sizeof ( *value ) ) ) )
+                        {
+                        goto Cleanup;
+                        }
+                    memset (value, 0, sizeof (*value));
+                    value->ve_valuename.num = 0;
+                    value->ve_valuename.var = psyment;
+                    if ( ! CAVLTreeAddNode(&names, value, NULL) )
+                        {
+                        free(value);
+                        goto Cleanup;
+                        }
+                    value->ve_type = 0;
+                    if ( ! CAVLTreeFindNode(&worklist, value) && ! CAVLTreeAddNode(&worklist, value, NULL) )
+                        {
+                        goto Cleanup;
+                        }
+                    continue;
+                    }
+
+                defs = SymGetDefInfo(psyment);
+                nChildren = DynamicArrayGetCount(defs);
+                for (i = 0; i < nChildren; i++)
+                    {
+                    def = DynamicArrayRetrieve(defs, i);
+                    if ( ! ( value = malloc ( sizeof ( *value ) ) ) )
+                        {
+                        goto Cleanup;
+                        }
+                    memset (value, 0, sizeof (*value));
+                    value->ve_valuename.num = def->count;
+                    value->ve_valuename.var = psyment;
+                    if ( ! CAVLTreeAddNode(&names, value, NULL) )
+                        {
+                        free(value);
+                        goto Cleanup;
+                        }
+
+                    if (IsInFilescope(SymGetScope(psyment)) && !SymIsConst(psyment, NULL, NULL))
+                        { // 全局变量,且不是常量
+                        value->ve_type = -1;
+                        if ( ! CAVLTreeFindNode(&worklist, value) && ! CAVLTreeAddNode(&worklist, value, NULL) )
+                            {
+                            goto Cleanup;
+                            }
+                        continue;
+                        }
+
+                    iop = ir_getOp(def->insn);
+
+                    if (iop == IRINST_OP_PHI)
+                        {
+                        value->ve_type = 1;
+                        }
+                    else if (iop == IRINST_OP_ENTRY)
+                        { // 参数
+                        value->ve_type = -1;
+                        }
+                    else if (iop == IRINST_OP_MEMSET)
+                        {
+                        value->ve_type = 0;
+                        }
+                    else if (iop == IRINST_OP_ASSIGN)
+                        {
+                        ir_GetOperand(def->insn, 0, &type, &isImmediate, &value->ve_value);
+                        if (!isImmediate)
+                            {
+                            value->ve_type = 1;
+                            }
+                        else
+                            {
+                            value->IsInteger = (type==Integer);
+                            }
+                        }
+                    else if (iop == IRINST_OP_FUNC_CALL)
+                        {
+                        value->ve_type = -1;
+                        }
+                    else if (iop == IRINST_OP_PLUS && DynamicArrayGetCount(Get_Dope(psyment)))
+                        {
+                        value->ve_type = -1;
+                        }
+                    else
+                        {
+                        value->ve_type = 1;
+                        }
+
+                    if (value->ve_type != 1)
+                        {
+                        if ( ! CAVLTreeFindNode(&worklist, value) && ! CAVLTreeAddNode(&worklist, value, NULL) )
+                            {
+                            goto Cleanup;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+	while ( CAVLTreeGetItemCount(&worklist) != 0 )
+		{
+		value = CAVLTreeGetIndexData(&worklist, 0);
+        CAVLTreeDelNodebyidx(&worklist, 0);
+        uses = SymGetUseInfo(value->ve_valuename.var);
+        n = (int)DynamicArrayGetCount(uses);
+        for ( i = 0; i < n; i++ )
+            {
+            use = DynamicArrayRetrieve(uses, i);
+            if (use->count != value->ve_valuename.num)
+                {
+                continue;
+                }
+
+            for (j=0; j < 3 ;j++ )
+                {
+                if (ir_isDef(use->insn, j))
+                    {
+                    if ( j == 0 )
+                        {
+                        psyment = ir_GetArgVoidPtr(use->insn, 1);
+                        }
+                    else if ( j == 1 )
+                        {
+                        psyment = ir_GetArgVoidPtr(use->insn, 0);
+                        }
+                    else
+                        {
+                        psyment = ir_GetDstVoidPtr(use->insn);
+                        }//
+                    dummy.ve_valuename.num = ir_GetNumber(use->insn, j);
+                    dummy.ve_valuename.var = psyment;
+                    if ( ! ( value2 = CAVLTreeFindNode ( &names, &dummy ) ) )
+                        {
+                        goto Cleanup;
+                        }
+                    if (value2->ve_type != -1)
+                        {
+                        saved = *value2;
+                        if (!evaluate(&names, value2, use->insn))
+                            {
+                            goto Cleanup;
+                            }
+                        if (memcmp (&saved, value2, sizeof(saved)) != 0 )
+                            {
+                            if ( ! CAVLTreeFindNode(&worklist, value2) && ! CAVLTreeAddNode(&worklist, value2, NULL) )
+                                {
+                                goto Cleanup;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+		}
+
+    n = cfg_GetBlockNumber (graph);
+    for (i = 0; i < n; i++)
+        {
+        bb = DynamicArrayRetrieve(&graph->bbs, i);
+        List_TRAVERSE(bb_GetInsts(bb), insn, &iterator)
+            {
+            iop = ir_getOp(insn);
+            if (iop == IRINST_OP_ARRAYASSIGN)
+                {
+                if (!ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1))
+                    {
+                    psyment = ir_GetArgVoidPtr(insn, 1);
+                    if (psyment != NULL && !DynamicArrayGetCount(Get_Dope(psyment)))
+                        {
+                        dummy.ve_valuename.num = ir_GetNumber(insn, 0);
+                        dummy.ve_valuename.var = psyment;
+                        if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) != NULL &&
+                            value->ve_type == 0 &&
+                            !SymIsRetval(psyment) &&
+                            !(IsInFilescope(SymGetScope(psyment)) && !SymIsConst(psyment, NULL, NULL)))
+                            {
+                            uses = SymGetUseInfo(psyment);
+                            nCount = (int)DynamicArrayGetCount(uses);
+                            for ( k=0; k<nCount; k++ )
+                                {
+                                use = DynamicArrayRetrieve(uses, k);
+                                if (use->count == dummy.ve_valuename.num &&
+                                    use->insn == insn)
+                                    {
+                                    DynArrayRemove2(uses, k);
+                                    break;
+                                    }
+                                }
+                            // PrintInstruction(stdout, insn, 0, 1);
+                            // printf(" -> ");
+                            SetImmediateValue(insn, value->IsInteger, 1, &value->ve_value);
+                            // PrintInstruction(stdout, insn, 0, 1);
+                            // printf("\n");
+                            }
+                        }
+                    }
+                }
+            else if (iop == IRINST_OP_ASSIGNARRAY)
+                {
+                if (!ir_IsArgFloat(insn, 0) && !ir_IsArgInteger(insn, 0) && !SymIsConst(ir_GetArgVoidPtr(insn, 0), NULL, NULL))
+                    {
+                    dummy.ve_valuename.var = ir_GetArgVoidPtr(insn, 0);
+                    dummy.ve_valuename.num = ir_GetNumber(insn, 1);
+                    if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) != NULL &&
+                        value->ve_type == 0 &&
+                        !SymIsRetval(dummy.ve_valuename.var) &&
+                        !(IsInFilescope(SymGetScope(dummy.ve_valuename.var)) && !SymIsConst(dummy.ve_valuename.var, NULL, NULL)))
+                        {
+                        uses = SymGetUseInfo(dummy.ve_valuename.var);
+                        nCount = (int)DynamicArrayGetCount(uses);
+                        for ( k=0; k<nCount; k++ )
+                            {
+                            use = DynamicArrayRetrieve(uses, k);
+                            if (use->count == dummy.ve_valuename.num &&
+                                use->insn == insn)
+                                {
+                                DynArrayRemove2(uses, k);
+                                break;
+                                }
+                            }
+                        // PrintInstruction(stdout, insn, 0, 1);
+                        // printf(" -> ");
+                        dummy.IsInteger = value->IsInteger;
+                        memcpy ( &dummy.ve_value, &value->ve_value, sizeof(dummy.ve_value) ) ;
+                        SetImmediateValue(insn,dummy.IsInteger, 0, &dummy.ve_value);
+                        // PrintInstruction(stdout, insn, 0, 1);
+                        // printf("\n");
+                        }
+                    if (value != NULL)
+                        {
+                        dummy.ve_type = value->ve_type;
+                        dummy.IsInteger = value->IsInteger;
+                        memcpy ( &dummy.ve_value, &value->ve_value, sizeof(dummy.ve_value) ) ;
+                        }
+                    }
+
+                dummy.ve_valuename.num = ir_GetNumber(insn, 0);
+                dummy.ve_valuename.var = ir_GetArgVoidPtr(insn, 1);
+                if (ir_IsArgInteger(insn, 0))
+                    {
+                    dummy.IsInteger = 1;
+                    dummy.ve_type = 0;
+                    dummy.ve_value.integer_val = ir_GetArgInteger(insn, 0);
+                    }
+                if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) != NULL &&
+                    value->ve_type == 0 && dummy.ve_type == 0 &&
+                    !SymIsRetval(dummy.ve_valuename.var) &&
+                    !(IsInFilescope(SymGetScope(dummy.ve_valuename.var)) && !SymIsConst(dummy.ve_valuename.var, NULL, NULL)))
+                    { // 变量数组
+                    // PrintInstruction(stdout, insn, 0, 1);
+                    // printf(" -> ");
+                    SymIsConst(dummy.ve_valuename.var, &type, NULL);
+                    if (!SymGetInitValueArray(dummy.ve_valuename.var, dummy.ve_value.integer_val / (type==Integer?SIZE_INTEGER : SIZE_FLOAT), &dummy.ve_value))
+                        {
+                        goto Cleanup;
+                        }
+                    ir_SetOp(insn, IRINST_OP_ASSIGN);
+                    SetImmediateValue(insn,type==Integer, 1, &dummy.ve_value);
+                    // PrintInstruction(stdout, insn, 0, 1);
+                    // printf("\n");
+                    }
+                }
+            else if (iop == IRINST_OP_MEMSET)
+                {
+        // do nothing
+                }
+            else if (iop == IRINST_OP_PHI)
+                {
+                bSkip = 0;
+                dummy.ve_valuename.num = ir_GetNumber(insn, 2);
+                dummy.ve_valuename.var = ir_GetDstVoidPtr(insn);
+                if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) != NULL &&
+                    value->ve_type == 0 &&
+                    !SymIsRetval(dummy.ve_valuename.var) &&
+                    !(IsInFilescope(SymGetScope(dummy.ve_valuename.var)) && !SymIsConst(dummy.ve_valuename.var, NULL, NULL)))
+                    {
+                    for ( j=0; j<phi_num_args(ir_GetArgVoidPtr(insn, 1)); j++ )
+                        {
+                        lpArg = phi_arg(ir_GetArgVoidPtr(insn, 1), j);
+                        dummy.ve_valuename.num = lpArg->iNumber;
+                        dummy.ve_valuename.var = lpArg->psyment;
+                        if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) == NULL ||
+                            value->ve_type == 1)
+                            {
+                            bSkip = 1;
+                            }
+                        }
+                    if (DynamicArrayGetCount(Get_Dope(dummy.ve_valuename.var)))
+                        {
+                        bSkip = 1;
+                        }
+
+                    if ( bSkip ) 
+                        continue;
+
+                    for ( j=0; j<phi_num_args(ir_GetArgVoidPtr(insn, 1)); j++ )
+                        {
+                        lpArg = phi_arg(ir_GetArgVoidPtr(insn, 1), j);
+                        uses = SymGetUseInfo(lpArg->psyment);
+                        nCount = (int)DynamicArrayGetCount(uses);
+                        for ( k=0; k<nCount; k++ )
+                            {
+                            use = DynamicArrayRetrieve(uses, k);
+                            if (use->count == lpArg->iNumber &&
+                                use->insn == insn)
+                                {
+                                DynArrayRemove2(uses, k);
+                                break;
+                                }
+                            }
+                        }
+                    // PrintInstruction(stdout, insn, 0, 1);
+                    // printf(" -> ");
+                    free (ir_GetArgVoidPtr(insn, 1));
+                    ir_SetOp(insn, IRINST_OP_ASSIGN);
+                    SetImmediateValue(insn, value->IsInteger, 1, &value->ve_value);
+                    // PrintInstruction(stdout, insn, 0, 1);
+                    // printf("\n");
+                    }
+                }
+            else
+                {
+                for (j=0; j < 4 ;j++ )
+                    {
+                    psyment = NULL;
+                    if (j == 0)
+                        {
+                        if (!ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1) && (!SymIsConst(ir_GetArgVoidPtr(insn, 1), NULL, NULL) || DynamicArrayGetCount(Get_Dope(ir_GetArgVoidPtr(insn, 1)))))
+                            {
+                            psyment = ir_GetArgVoidPtr(insn, 1);
+                            }
+                        }
+                    else if (j == 1)
+                        {
+                        if (!ir_IsArgFloat(insn, 0) && !ir_IsArgInteger(insn, 0) && !SymIsConst(ir_GetArgVoidPtr(insn, 0), NULL, NULL))
+                            {
+                            psyment = ir_GetArgVoidPtr(insn, 0);
+                            }
+                        }
+                    else if (j == 2)
+                        {
+                        psyment = NULL;
+                        }
+                    else if (ir_getOp(insn)==IRINST_OP_ARRAYASSIGN)
+                        {
+                        psyment = ir_GetDstVoidPtr(insn);
+                        }
+                    else if (ir_getOp(insn)==IRINST_OP_PLUS && !ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1) && DynamicArrayGetCount(Get_Dope(ir_GetArgVoidPtr(insn, 1))))
+                        {
+                        psyment = ir_GetArgVoidPtr(insn, 1);
+                        }
+
+                    if (psyment != NULL && !DynamicArrayGetCount(Get_Dope(psyment)))
+                        {
+                        dummy.ve_valuename.num = ir_GetNumber(insn, j);
+                        dummy.ve_valuename.var = psyment;
+                        if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) != NULL &&
+                            value->ve_type == 0 &&
+                            !SymIsRetval(psyment) &&
+                            !(IsInFilescope(SymGetScope(psyment)) && !SymIsConst(psyment, NULL, NULL)))
+                            {
+    //	暂时不对全局变量进行常量传播,因为:
+    //  1) 函数调用可能会更改全局变量。
+    //  2) 一个函数可能直接使用全局变量,而找不到的定值。
+    //
+            //	删除此变量在此处的使用信息
+                            uses = SymGetUseInfo(psyment);
+                            nCount = (int)DynamicArrayGetCount(uses);
+                            for ( k=0; k<nCount; k++ )
+                                {
+                                use = DynamicArrayRetrieve(uses, k);
+                                if (use->count == dummy.ve_valuename.num &&
+                                    use->insn == insn)
+                                    {
+                                    DynArrayRemove2(uses, k);
+                                    break;
+                                    }
+                                }
+                            // PrintInstruction(stdout, insn, 0, 1);
+                            // printf(" -> ");
+                            SetImmediateValue(insn, value->IsInteger, j==0, &value->ve_value);
+                            // PrintInstruction(stdout, insn, 0, 1);
+                            // printf("\n");
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+    bSuccess = 1;
+Cleanup:
+    FinalizeAVLTree(&worklist, NULL);
+    FinalizeAVLTree(&names, NULL);
+    DynamicArrayDestroy(&tmpqueue);
+    DynamicArrayDestroy(&MyQueue);
+    return bSuccess;
+}