+ 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;
+ }