X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fhc08%2Fgen.c;h=9c94f3559b73891c3037ce99b0dc5e295720476e;hb=0694926e60ec83b31f87590e601f7e0d8f86c512;hp=29637fae83cd5edb872d0705fbeac5667f4097b4;hpb=8cd2c0dc8d10158574c765544ae47f2a7ae2a53e;p=fw%2Fsdcc diff --git a/src/hc08/gen.c b/src/hc08/gen.c index 29637fae..9c94f355 100644 --- a/src/hc08/gen.c +++ b/src/hc08/gen.c @@ -1352,7 +1352,7 @@ static asmop * aopForRemat (symbol * sym) { iCode *ic = sym->rematiCode; - asmop *aop = newAsmop (AOP_IMMD); + asmop *aop = NULL; int ptr_type=0; int val = 0; @@ -1377,22 +1377,40 @@ aopForRemat (symbol * sym) ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode; } - if (val) - sprintf (buffer, "(%s %c 0x%04x)", - OP_SYMBOL (IC_LEFT (ic))->rname, - val >= 0 ? '+' : '-', - abs (val) & 0xffff); - else - strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname); + if (ic->op == ADDRESS_OF) + { + if (val) + sprintf (buffer, "(%s %c 0x%04x)", + OP_SYMBOL (IC_LEFT (ic))->rname, + val >= 0 ? '+' : '-', + abs (val) & 0xffff); + else + strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname); - aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1); - strcpy (aop->aopu.aop_immd.aop_immd1, buffer); - /* set immd2 field if required */ - if (aop->aopu.aop_immd.from_cast_remat) { + aop = newAsmop (AOP_IMMD); + aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1); + strcpy (aop->aopu.aop_immd.aop_immd1, buffer); + /* set immd2 field if required */ + if (aop->aopu.aop_immd.from_cast_remat) + { sprintf(buffer,"#0x%02x",ptr_type); aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1); strcpy (aop->aopu.aop_immd.aop_immd2, buffer); - } + } + } + else if (ic->op == '=') + { + val += (int) operandLitValue (IC_RIGHT (ic)); + val &= 0xffff; + sprintf (buffer, "0x%04x", val); + aop = newAsmop (AOP_LIT); + aop->aopu.aop_lit = constVal (buffer); + } + else + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "unexpected rematerialization"); + + return aop; } @@ -1902,7 +1920,7 @@ aopAdrStr (asmop * aop, int loffset, bool bit16) case AOP_LIT: if (bit16) - return aopLiteralLong (aop->aopu.aop_lit, loffset, 2); + return aopLiteralLong (aop->aopu.aop_lit, /*loffset*/ 0, 2); else return aopLiteral (aop->aopu.aop_lit, loffset); @@ -2080,9 +2098,12 @@ asmopToBool (asmop *aop, bool resultInA) emitcode ("", "%05d$:", (tlbl->key + 100)); } else - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "Bad rIdx in asmToBool"); - return; + { + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "Bad rIdx in asmToBool"); + return; + } + break; case AOP_EXT: if (resultInA) needpula = FALSE; @@ -3325,6 +3346,8 @@ genMinus (iCode * ic) { char *sub; int size, offset = 0; + + asmop *leftOp, *rightOp; D(emitcode ("; genMinus","")); @@ -3340,7 +3363,6 @@ genMinus (iCode * ic) size = getDataSize (IC_RESULT (ic)); - asmop *leftOp, *rightOp; leftOp = AOP(IC_LEFT(ic)); rightOp = AOP(IC_RIGHT(ic)); @@ -4964,11 +4986,59 @@ genGetHbit (iCode * ic) emitcode ("rola", ""); hc08_dirtyReg (hc08_reg_a, FALSE); storeRegToFullAop (hc08_reg_a, AOP (result), FALSE); + hc08_freeReg (hc08_reg_a); freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } +/*-----------------------------------------------------------------*/ +/* genSwap - generates code to swap nibbles or bytes */ +/*-----------------------------------------------------------------*/ +static void +genSwap (iCode * ic) +{ + operand *left, *result; + + D(emitcode ("; genSwap","")); + + left = IC_LEFT (ic); + result = IC_RESULT (ic); + aopOp (left, ic, FALSE); + aopOp (result, ic, FALSE); + + switch (AOP_SIZE (left)) + { + case 1: /* swap nibbles in byte */ + loadRegFromAop (hc08_reg_a, AOP (left), 0); + emitcode ("nsa", ""); + hc08_dirtyReg (hc08_reg_a, FALSE); + storeRegToAop (hc08_reg_a, AOP (result), 0); + hc08_freeReg (hc08_reg_a); + break; + case 2: /* swap bytes in a word */ + if (operandsEqu (left, result)) + { + loadRegFromAop (hc08_reg_a, AOP (left), 0); + hc08_useReg (hc08_reg_a); + transferAopAop (AOP (left), 1, AOP (result), 0); + storeRegToAop (hc08_reg_a, AOP (result), 1); + hc08_freeReg (hc08_reg_a); + } + else + { + transferAopAop (AOP (left), 0, AOP (result), 1); + transferAopAop (AOP (left), 1, AOP (result), 0); + } + break; + default: + wassertl(FALSE, "unsupported SWAP operand size"); + } + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (result, NULL, ic, TRUE); +} + #if 0 /*-----------------------------------------------------------------*/ /* AccRol - rotate left accumulator by known count */ @@ -5276,7 +5346,7 @@ XAccRsh (int shCount, bool sign) return; } - shCount &= 0x000f; // shCount : 0..7 + shCount &= 0x000f; // shCount : 0..f /* if we can beat 2n cycles or bytes for some special case, do it here */ switch (shCount) @@ -5304,7 +5374,7 @@ XAccRsh (int shCount, bool sign) ** rola 1 1 bcde fgh0 0000 000a 0 ** lslx 1 1 cdef gh00 0000 000a b ** rola 1 1 cdef gh00 0000 00ab 0 - ** clrx 1 1 0000 0000 0000 000a 0 + ** clrx 1 1 0000 0000 0000 00ab 0 ** total: 6 cycles, 6 bytes */ loadRegFromConst (hc08_reg_x, zero); @@ -5360,12 +5430,12 @@ XAccRsh (int shCount, bool sign) ; } - /* lslx/rola is only 2 cycles and bytes, so an unrolled loop is often */ + /* lsrx/rora is only 2 cycles and bytes, so an unrolled loop is often */ /* the fastest and shortest. */ for (i=0;ia:x->c by 1 */ -/*-----------------------------------------------------------------*/ -static void -AccAXRsh1 (char *x) -{ - emitcode ("lsra", ""); - emitcode ("ror", "%s", x); -} - - -/*-----------------------------------------------------------------*/ -/* AccAXRshS1 - signed right shift s->a:x->c by 1 */ -/*-----------------------------------------------------------------*/ -static void -AccAXRshS1 (char *x) -{ - emitcode ("asra", ""); - emitcode ("ror", "%s", x); -} - -/*-----------------------------------------------------------------*/ -/* AccAXLrl1 - left rotate c<-a:x<-c by 1 */ -/*-----------------------------------------------------------------*/ -static void -AccAXLrl1 (char *x) -{ - emitcode ("rol", "%s", x); - emitcode ("rola", ""); -} - -/*-----------------------------------------------------------------*/ -/* AccAXLsh1 - left shift a:x<-0 by 1 */ -/*-----------------------------------------------------------------*/ -static void -AccAXLsh1 (char *x) -{ - emitcode ("lsl", "%s", x); - emitcode ("rola", ""); -} - -/*-----------------------------------------------------------------*/ -/* AccAXLsh - left shift a:x by known count (0..7) */ -/*-----------------------------------------------------------------*/ -static void -AccAXLsh (char *x, int shCount) -{ - int i; - - for (i=0;i= 8 */ @@ -5633,10 +5623,9 @@ genlshTwo (operand * result, operand * left, int shCount) if (size > 1) { - if (shCount) - shiftL1Left2Result (left, LSB, result, MSB16, shCount); - else - movLeft2Result (left, LSB, result, MSB16, 0); + loadRegFromAop (hc08_reg_a, AOP (left), 0); + AccLsh (shCount); + storeRegToAop (hc08_reg_a, AOP (result), 1); } storeConstToAop(zero, AOP (result), LSB); } @@ -5644,10 +5633,9 @@ genlshTwo (operand * result, operand * left, int shCount) /* 1 <= shCount <= 7 */ else { - if (size == 1) - shiftL1Left2Result (left, LSB, result, LSB, shCount); - else - shiftL2Left2Result (left, LSB, result, LSB, shCount); + loadRegFromAop (hc08_reg_xa, AOP (left), 0); + XAccLsh (shCount); + storeRegToFullAop (hc08_reg_xa, AOP (result), 0); } } @@ -6342,6 +6330,7 @@ genDataPointerGet (operand * left, freeAsmop (result, NULL, ic, TRUE); } +#if 0 /*-----------------------------------------------------------------*/ /* genNearPointerGet - emitcode for near pointer fetch */ /*-----------------------------------------------------------------*/ @@ -6414,9 +6403,8 @@ genNearPointerGet (operand * left, } hc08_freeReg (hc08_reg_hx); - } - +#endif /*-----------------------------------------------------------------*/ /* genFarPointerGet - get value from far space */ @@ -6521,7 +6509,7 @@ genPointerGet (iCode * ic, iCode *pi) } /* special case when cast remat */ - if (p_type == GPOINTER && OP_SYMBOL(left)->remat && + if (p_type == GPOINTER && IS_SYMOP(left) && OP_SYMBOL(left)->remat && IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) { left = IC_RIGHT(OP_SYMBOL(left)->rematiCode); type = operandType (left); @@ -6663,6 +6651,7 @@ genPackBits (sym_link * etype, emitcode ("and", "#0x%02x", mask); emitcode ("ora", "1,s"); emitcode ("sta", ",x"); + pullReg (hc08_reg_a); } hc08_freeReg (hc08_reg_a); @@ -6698,6 +6687,7 @@ genDataPointerSet (operand * right, freeAsmop (NULL, derefaop, ic, TRUE); } +#if 0 /*-----------------------------------------------------------------*/ /* genNearPointerSet - emitcode for near pointer put */ /*-----------------------------------------------------------------*/ @@ -6769,7 +6759,7 @@ genNearPointerSet (operand * right, hc08_freeReg (hc08_reg_hx); } - +#endif /*-----------------------------------------------------------------*/ /* genFarPointerSet - set value from far space */ @@ -7249,6 +7239,10 @@ genDjnz (iCode * ic, iCode * ifx) if (operandLitValue (IC_RIGHT (ic)) != 1) return 0; + /* dbnz doesn't support extended mode */ + if (isOperandInFarSpace (IC_RESULT (ic))) + return 0; + /* if the size of this greater than one then no saving */ // if (getSize (operandType (IC_RESULT (ic))) > 1) @@ -7305,6 +7299,85 @@ genReceive (iCode * ic) freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); } +/*-----------------------------------------------------------------*/ +/* genDummyRead - generate code for dummy read of volatiles */ +/*-----------------------------------------------------------------*/ +static void +genDummyRead (iCode * ic) +{ + operand *right; + int size, offset; + + D(emitcode("; genDummyRead","")); + + right = IC_RIGHT (ic); + + aopOp (right, ic, FALSE); + + /* bit variables done */ + /* general case */ + size = AOP_SIZE (right); + offset = 0; + + while (size--) + { + loadRegFromAop (hc08_reg_a, AOP (right), offset); + hc08_freeReg (hc08_reg_a); + offset++; + } + + freeAsmop (right, NULL, ic, TRUE); +} + +/*-----------------------------------------------------------------*/ +/* genCritical - generate code for start of a critical sequence */ +/*-----------------------------------------------------------------*/ +static void +genCritical (iCode *ic) +{ + D(emitcode("; genCritical","")); + + if (IC_RESULT (ic)) + aopOp (IC_RESULT (ic), ic, TRUE); + + emitcode ("tpa", ""); + hc08_dirtyReg (hc08_reg_a, FALSE); + emitcode ("sei", ""); + + if (IC_RESULT (ic)) + storeRegToAop (hc08_reg_a, AOP (IC_RESULT (ic)), 0); + else + pushReg (hc08_reg_a, FALSE); + + hc08_freeReg (hc08_reg_a); + if (IC_RESULT (ic)) + freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); +} + +/*-----------------------------------------------------------------*/ +/* genEndCritical - generate code for end of a critical sequence */ +/*-----------------------------------------------------------------*/ +static void +genEndCritical (iCode *ic) +{ + D(emitcode("; genEndCritical","")); + + if (IC_RIGHT (ic)) + { + aopOp (IC_RIGHT (ic), ic, FALSE); + loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (ic)), 0); + emitcode ("tap", ""); + hc08_freeReg (hc08_reg_a); + freeAsmop (IC_RIGHT (ic), NULL, ic, TRUE); + } + else + { + pullReg (hc08_reg_a); + emitcode ("tap", ""); + } +} + + /*-----------------------------------------------------------------*/ /* genhc08Code - generate code for HC08 based controllers */ /*-----------------------------------------------------------------*/ @@ -7616,6 +7689,22 @@ genhc08Code (iCode * lic) addSet (&_G.sendSet, ic); break; + case DUMMY_READ_VOLATILE: + genDummyRead (ic); + break; + + case CRITICAL: + genCritical (ic); + break; + + case ENDCRITICAL: + genEndCritical (ic); + break; + + case SWAP: + genSwap (ic); + break; + default: ic = ic; }