- 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,<(%d)",
- aopGet (AOP (IC_LEFT (ic)), 0), lit);
- }
- else {
- MOVR24 (aopGet (AOP (IC_LEFT (ic)), 0));
- emitcode (bopnames_lit[bitop], "r24,<(%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,<(%d)", lit);
- emitcode (bopnames_lit[bitop], "r25,>(%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,<(%d)",
- aopGet (AOP (IC_LEFT (ic)), offset),
- lit);
- }
- else {
- char *l = aopGet (AOP (IC_LEFT (ic)), offset);
- MOVR24 (l);
- emitcode ("andi", "r24,<(%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++;
- }
+ 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) ulFromVal (AOP (right)->aopu.
+ aop_lit);
+ int p2 = powof2 (lit);
+ if (bitop == AVR_AND && (p2 >= 0)) { /* 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,<(%d)",
+ aopGet (AOP (IC_LEFT (ic)), 0), lit);
+ }
+ else {
+ MOVR24 (aopGet (AOP (IC_LEFT (ic)), 0));
+ emitcode (bopnames_lit[bitop], "r24,<(%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,<(%d)", lit);
+ emitcode (bopnames_lit[bitop], "r25,>(%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,<(%d)",
+ aopGet (AOP (IC_LEFT (ic)), offset),
+ lit);
+ }
+ else {
+ char *l = aopGet (AOP (IC_LEFT (ic)), offset);
+ MOVR24 (l);
+ emitcode ("andi", "r24,<(%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) ulFromVal (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) ulFromVal (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++;
+ }