- operand *left, *right, *result;
- int size, offset=0;
- char *l;
- symbol *lbl, *lbl1;
- int samerl, samerr ;
-
- aopOp((left = IC_LEFT(ic)),ic,FALSE);
- aopOp((right= IC_RIGHT(ic)),ic,FALSE);
- aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
- size = AOP_SIZE(left);
- offset = 0;
- if (ifx) { /* used only for jumps */
- if (AOP_TYPE(right) == AOP_LIT &&
- (bitop == AVR_AND || bitop == AVR_OR)) {
- int lit = (int) floatFromVal (AOP(right)->aopu.aop_lit);
- int p2 = powof2(lit);
- if (bitop == AVR_AND && p2) { /* right side is a power of 2 */
- l = aopGet(AOP(left),p2 / 8);
- if (IC_TRUE(ifx)) {
- emitcode("sbrc","%s,%d",l,(p2 % 8));
- emitcode("rjmp","L%05d",IC_TRUE(ifx)->key);
- } else {
- emitcode("sbrs","%s,%d",l,(p2 % 8));
- emitcode("rjmp","L%05d",IC_FALSE(ifx)->key);
- }
- } else { /* right not power of two */
- int eh = OP_SYMBOL(left)->liveTo <= ic->seq;
- if (size == 1) {
- if (eh) {
- emitcode(bopnames_lit[bitop],"%s,lo8(%d)",
- aopGet(AOP(IC_LEFT(ic)),0), lit);
- } else {
- MOVR0(aopGet(AOP(IC_LEFT(ic)),0));
- emitcode(bopnames_lit[bitop],"r0,lo8(%d)",lit);
- }
- lbl = newiTempLabel(NULL);
- if (IC_TRUE(ifx)) {
- emitcode("breq","L%05d",lbl->key);
- emitcode("rjmp","L%05d",IC_TRUE(ifx)->key);
- } else {
- emitcode("brne","L%05d",lbl->key);
- emitcode("rjmp","L%05d",IC_FALSE(ifx)->key);
- }
- emitcode("","L%05d:",lbl->key);
- } else if (size == 2) {
- emitcode("mov","r24,%s",aopGet(AOP(IC_LEFT(ic)),0));
- emitcode("mov","r25,%s",aopGet(AOP(IC_LEFT(ic)),1));
- emitcode(bopnames_lit[bitop],"r24,lo8(%d)",lit);
- emitcode(bopnames_lit[bitop],"r25,hi8(%d)",lit);
- emitcode("sbiw","r24,0");
- lbl = newiTempLabel(NULL);
- if (IC_TRUE(ifx)) {
- emitcode("breq","L%05d",lbl->key);
- emitcode("rjmp","L%05d",IC_TRUE(ifx)->key);
- } else {
- emitcode("brne","L%05d",lbl->key);
- emitcode("rjmp","L%05d",IC_FALSE(ifx)->key);
- }
- emitcode("","L%05d:",lbl->key);
- } else {
- lbl = newiTempLabel(NULL);
- lbl1 = newiTempLabel(NULL);
- while (size--) {
- if (eh) {
- emitcode(bopnames_lit[bitop],"%s,lo8(%d)",
- aopGet(AOP(IC_LEFT(ic)),offset), lit);
- } else {
- MOVR0(aopGet(AOP(IC_LEFT(ic)),offset));
- emitcode("andi","r0,lo8(%d)",lit);
- }
- emitcode("brne","L%05d",lbl->key);
- offset++;
- }
- /* all are zero */
- if (IC_FALSE(ifx)) emitcode("rjmp","L%05d",IC_FALSE(ifx)->key);
- else emitcode("rjmp","L%05d",lbl1->key);
- emitcode("","L%05d:",lbl->key);
- /* not zero */
- if (IC_TRUE(ifx)) emitcode("rjmp","L%05d",IC_TRUE(ifx)->key);
- emitcode("","L%05d:",lbl1->key);
-
- }
- }
- } else { /* right is not a literal */
- int eh = OP_SYMBOL(left)->liveTo <= ic->seq;
- int reh = OP_SYMBOL(right)->liveTo <= ic->seq;
- if (size == 1) {
- if (eh) {
- emitcode(bopnames[bitop],"%s,%s",
- aopGet(AOP(IC_LEFT(ic)),0),
- aopGet(AOP(IC_RIGHT(ic)),0));
- } else if (reh) {
- emitcode(bopnames[bitop],"%s,%s",
- aopGet(AOP(IC_RIGHT(ic)),0),
- aopGet(AOP(IC_LEFT(ic)),0));
- } else {
- MOVR0(aopGet(AOP(IC_LEFT(ic)),0));
- emitcode(bopnames[bitop],"r0,%s",aopGet(AOP(IC_RIGHT(ic)),0));
- }
- lbl = newiTempLabel(NULL);
- if (IC_TRUE(ifx)) {
- emitcode("breq","L%05d",lbl->key);
- emitcode("rjmp","L%05d",IC_TRUE(ifx)->key);
- } else {
- emitcode("brne","L%05d",lbl->key);
- emitcode("rjmp","L%05d",IC_FALSE(ifx)->key);
- }
- emitcode("","L%05d:",lbl->key);
- } else if (size == 2) {
- emitcode("mov","r24,%s",aopGet(AOP(IC_LEFT(ic)),0));
- emitcode("mov","r25,%s",aopGet(AOP(IC_LEFT(ic)),1));
- emitcode(bopnames[bitop],"r24,%s",aopGet(AOP(IC_RIGHT(ic)),0));
- emitcode(bopnames[bitop],"r25,%s",aopGet(AOP(IC_RIGHT(ic)),1));
- emitcode("sbiw","r24,0");
- lbl = newiTempLabel(NULL);
- if (IC_TRUE(ifx)) {
- emitcode("breq","L%05d",lbl->key);
- emitcode("rjmp","L%05d",IC_TRUE(ifx)->key);
- } else {
- emitcode("brne","L%05d",lbl->key);
- emitcode("rjmp","L%05d",IC_FALSE(ifx)->key);
- }
- emitcode("","L%05d:",lbl->key);
- } else {
- lbl = newiTempLabel(NULL);
- lbl1 = newiTempLabel(NULL);
- while (size--) {
- if (eh) {
- emitcode(bopnames[bitop],"%s,%s",
- aopGet(AOP(IC_LEFT(ic)),offset),
- aopGet(AOP(IC_RIGHT(ic)),offset));
- } else if (reh) {
- emitcode(bopnames[bitop],"%s,%s",
- aopGet(AOP(IC_RIGHT(ic)),offset),
- aopGet(AOP(IC_LEFT(ic)),offset));
- } else {
- MOVR0(aopGet(AOP(IC_LEFT(ic)),offset));
- emitcode(bopnames[bitop],"r0,%s",aopGet(AOP(IC_RIGHT(ic)),offset));
- }
- emitcode("brne","L%05d",lbl->key);
- offset++;
- }
- /* all are zero */
- if (IC_FALSE(ifx)) emitcode("rjmp","L%05d",IC_FALSE(ifx)->key);
- else emitcode("rjmp","L%05d",lbl1->key);
- emitcode("","L%05d:",lbl->key);
- /* not zero */
- if (IC_TRUE(ifx)) emitcode("rjmp","L%05d",IC_TRUE(ifx)->key);
- emitcode("","L%05d:",lbl1->key);
-
- }
- }
- goto release ;
- }
-
- /* result needs to go a register */
- samerl = sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)));
- samerr = sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)));
- while (size--) {
- if (AOP_TYPE(right) == AOP_LIT) {
- unsigned int lit = (int) floatFromVal (AOP(right)->aopu.aop_lit);
- if (((lit >> (8*offset)) & 0xff) == 0) {
- if (bitop == AVR_AND) {
- aopPut(AOP(result),zero,offset++);
- continue;
- } else if (bitop == AVR_OR) {
- if (!samerl)
- aopPut(AOP(result),aopGet(AOP(left),offset),offset);
- offset++;
- continue;
- }
- }
- }
- if (samerl) {
- if (AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT && (bitop == AVR_AND || bitop == AVR_OR)) {
- emitcode(bopnames_lit[bitop],"%s,%s(%d)",aopGet(AOP(IC_LEFT(ic)),offset),
- larray[offset],(int) floatFromVal (AOP(right)->aopu.aop_lit));
- } else {
- emitcode(bopnames[bitop],"%s,%s",aopGet(AOP(IC_LEFT(ic)),offset),
- aopGet(AOP(IC_RIGHT(ic)),offset));
- }
- } else if (samerr) {
- emitcode(bopnames[bitop],"%s,%s",aopGet(AOP(IC_RIGHT(ic)),offset),
- aopGet(AOP(IC_LEFT(ic)),offset));
- } else {
- aopPut(AOP(IC_RESULT(ic)),aopGet(AOP(IC_LEFT(ic)),offset),offset);
- emitcode(bopnames[bitop],aopGet(AOP(IC_RESULT(ic)),offset),
- aopGet(AOP(IC_RIGHT(ic)),offset));
- }
- offset++;
- }
-release :
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
-}
+ operand *left, *right, *result;
+ int size, offset = 0;
+ char *l;
+ symbol *lbl, *lbl1;
+ int samerl, samerr;
+
+ aopOp ((left = IC_LEFT (ic)), ic, FALSE);
+ aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
+ aopOp ((result = IC_RESULT (ic)), ic, TRUE);
+
+ size = AOP_SIZE (left);
+ offset = 0;
+ if (ifx) { /* used only for jumps */
+ if (AOP_TYPE (right) == AOP_LIT &&
+ (bitop == AVR_AND || bitop == AVR_OR)) {
+ int lit =
+ (int) floatFromVal (AOP (right)->aopu.
+ aop_lit);
+ int p2 = powof2 (lit);
+ if (bitop == AVR_AND && p2) { /* right side is a power of 2 */
+ l = aopGet (AOP (left), p2 / 8);
+ if (IC_TRUE (ifx)) {
+ emitcode ("sbrc", "%s,%d", l,
+ (p2 % 8));
+ emitcode ("rjmp", "L%05d",
+ IC_TRUE (ifx)->key);
+ }
+ else {
+ emitcode ("sbrs", "%s,%d", l,
+ (p2 % 8));
+ emitcode ("rjmp", "L%05d",
+ IC_FALSE (ifx)->key);
+ }
+ }
+ else { /* right not power of two */
+ int eh = OP_SYMBOL (left)->liveTo <= ic->seq;
+ if (size == 1) {
+ if (eh && AOP_ISHIGHREG(AOP(IC_LEFT(ic)),0)) {
+ emitcode (bopnames_lit[bitop],
+ "%s,lo8(%d)",
+ aopGet (AOP (IC_LEFT (ic)), 0), lit);
+ }
+ else {
+ MOVR24 (aopGet (AOP (IC_LEFT (ic)), 0));
+ emitcode (bopnames_lit[bitop], "r24,lo8(%d)", lit);
+ }
+ lbl = newiTempLabel (NULL);
+ if (IC_TRUE (ifx)) {
+ emitcode ("breq", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+ }
+ else {
+ emitcode ("brne", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_FALSE (ifx)-> key);
+ }
+ emitcode ("", "L%05d:", lbl->key);
+ }
+ else if (size == 2) {
+ emitcode ("mov", "r24,%s", aopGet (AOP (IC_LEFT (ic)), 0));
+ emitcode ("mov", "r25,%s", aopGet (AOP (IC_LEFT (ic)), 1));
+ emitcode (bopnames_lit[bitop], "r24,lo8(%d)", lit);
+ emitcode (bopnames_lit[bitop], "r25,hi8(%d)", lit);
+ emitcode ("sbiw", "r24,0");
+ lbl = newiTempLabel (NULL);
+ if (IC_TRUE (ifx)) {
+ emitcode ("breq", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+ }
+ else {
+ emitcode ("brne", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
+ }
+ emitcode ("", "L%05d:", lbl->key);
+ }
+ else {
+ lbl = newiTempLabel (NULL);
+ lbl1 = newiTempLabel (NULL);
+ while (size--) {
+ if (eh && AOP_ISHIGHREG(AOP(IC_LEFT(ic)),offset)) {
+ emitcode (bopnames_lit [bitop], "%s,lo8(%d)",
+ aopGet (AOP (IC_LEFT (ic)), offset),
+ lit);
+ }
+ else {
+ char *l = aopGet (AOP (IC_LEFT (ic)), offset);
+ MOVR24 (l);
+ emitcode ("andi", "r24,lo8(%d)", lit);
+ }
+ emitcode ("brne", "L%05d", lbl->key);
+ offset++;
+ }
+ /* all are zero */
+ if (IC_FALSE (ifx))
+ emitcode ("rjmp", "L%05d", IC_FALSE (ifx)-> key);
+ else
+ emitcode ("rjmp", "L%05d", lbl1->key);
+ emitcode ("", "L%05d:", lbl->key);
+ /* not zero */
+ if (IC_TRUE (ifx))
+ emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+ emitcode ("", "L%05d:", lbl1->key);
+
+ }
+ }
+ }
+ else { /* right is not a literal */
+ int eh = OP_SYMBOL (left)->liveTo <= ic->seq;
+ int reh = OP_SYMBOL (right)->liveTo <= ic->seq;
+ if (size == 1) {
+ if (eh) {
+ emitcode (bopnames[bitop], "%s,%s", aopGet (AOP (IC_LEFT (ic)), 0),
+ aopGet (AOP (IC_RIGHT (ic)), 0));
+ }
+ else if (reh) {
+ emitcode (bopnames[bitop], "%s,%s",
+ aopGet (AOP (IC_RIGHT (ic)), 0),
+ aopGet (AOP (IC_LEFT (ic)), 0));
+ }
+ else {
+ MOVR0 (aopGet (AOP (IC_LEFT (ic)), 0));
+ emitcode (bopnames[bitop], "r0,%s",
+ aopGet (AOP (IC_RIGHT (ic)), 0));
+ }
+ lbl = newiTempLabel (NULL);
+ if (IC_TRUE (ifx)) {
+ emitcode ("breq", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d",
+ IC_TRUE (ifx)->key);
+ }
+ else {
+ emitcode ("brne", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d",
+ IC_FALSE (ifx)->key);
+ }
+ emitcode ("", "L%05d:", lbl->key);
+ }
+ else if (size == 2) {
+ emitcode ("mov", "r24,%s",
+ aopGet (AOP (IC_LEFT (ic)), 0));
+ emitcode ("mov", "r25,%s",
+ aopGet (AOP (IC_LEFT (ic)), 1));
+ emitcode (bopnames[bitop], "r24,%s",
+ aopGet (AOP (IC_RIGHT (ic)), 0));
+ emitcode (bopnames[bitop], "r25,%s",
+ aopGet (AOP (IC_RIGHT (ic)), 1));
+ emitcode ("sbiw", "r24,0");
+ lbl = newiTempLabel (NULL);
+ if (IC_TRUE (ifx)) {
+ emitcode ("breq", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+ }
+ else {
+ emitcode ("brne", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
+ }
+ emitcode ("", "L%05d:", lbl->key);
+ }
+ else {
+ lbl = newiTempLabel (NULL);
+ lbl1 = newiTempLabel (NULL);
+ while (size--) {
+ if (eh) {
+ emitcode (bopnames[bitop], "%s,%s",
+ aopGet (AOP (IC_LEFT (ic)), offset),
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ else if (reh) {
+ emitcode (bopnames[bitop], "%s,%s",
+ aopGet (AOP (IC_RIGHT (ic)), offset),
+ aopGet (AOP (IC_LEFT (ic)), offset));
+ }
+ else {
+ MOVR0 (aopGet (AOP (IC_LEFT (ic)), offset));
+ emitcode (bopnames[bitop], "r0,%s",
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ emitcode ("brne", "L%05d", lbl->key);
+ offset++;
+ }
+ /* all are zero */
+ if (IC_FALSE (ifx))
+ emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
+ else
+ emitcode ("rjmp", "L%05d", lbl1->key);
+ emitcode ("", "L%05d:", lbl->key);
+ /* not zero */
+ if (IC_TRUE (ifx))
+ emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+ emitcode ("", "L%05d:", lbl1->key);
+
+ }
+ }
+ goto release;
+ }
+
+ /* result needs to go a register */
+ samerl = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)));
+ samerr = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic)));
+ while (size--) {
+ if (AOP_TYPE (right) == AOP_LIT) {
+ unsigned int lit =
+ (int) floatFromVal (AOP (right)->aopu.
+ aop_lit);
+ if (((lit >> (8 * offset)) & 0xff) == 0) {
+ if (bitop == AVR_AND) {
+ aopPut (AOP (result), zero, offset++);
+ continue;
+ }
+ else if (bitop == AVR_OR) {
+ if (!samerl)
+ aopPut (AOP (result),
+ aopGet (AOP (left),
+ offset),
+ offset);
+ offset++;
+ continue;
+ }
+ }
+ }
+ if (samerl) {
+ if (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT &&
+ AOP_ISHIGHREG(AOP(IC_LEFT(ic)),offset) &&
+ (bitop == AVR_AND || bitop == AVR_OR)) {
+ emitcode (bopnames_lit[bitop], "%s,%s(%d)",
+ aopGet (AOP (IC_LEFT (ic)), offset),
+ larray[offset],
+ (int) floatFromVal (AOP (right)-> aopu.aop_lit));
+ }
+ else {
+ emitcode (bopnames[bitop], "%s,%s",
+ aopGet (AOP (IC_LEFT (ic)), offset),
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ }
+ else if (samerr) {
+ emitcode (bopnames[bitop], "%s,%s",
+ aopGet (AOP (IC_RIGHT (ic)), offset),
+ aopGet (AOP (IC_LEFT (ic)), offset));
+ }
+ else {
+ aopPut (AOP (IC_RESULT (ic)),
+ aopGet (AOP (IC_LEFT (ic)), offset), offset);
+ emitcode (bopnames[bitop],
+ aopGet (AOP (IC_RESULT (ic)), offset),
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ offset++;
+ }
+ release:
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (result, NULL, ic, TRUE);
+}