Annotation of gcc/output-m88k.c, revision 1.1.1.4

1.1       root        1: /* Subroutines for insn-output.c for Motorola 88000.
                      2:    Copyright (C) 1987 Free Software Foundation, Inc.
                      3:    Contributed by Michael Tiemann ([email protected])
                      4: 
                      5: This file is part of GNU CC.
                      6: 
1.1.1.4 ! root        7: GNU CC is free software; you can redistribute it and/or modify
        !             8: it under the terms of the GNU General Public License as published by
        !             9: the Free Software Foundation; either version 1, or (at your option)
        !            10: any later version.
        !            11: 
1.1       root       12: GNU CC is distributed in the hope that it will be useful,
1.1.1.4 ! root       13: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            15: GNU General Public License for more details.
        !            16: 
        !            17: You should have received a copy of the GNU General Public License
        !            18: along with GNU CC; see the file COPYING.  If not, write to
        !            19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
1.1       root       20: 
                     21: #ifndef FILE
                     22: #include <stdio.h>
                     23: #endif
                     24: 
                     25: /* This is where the condition code register lives.  */
                     26: rtx cc0_reg_rtx;
                     27: 
                     28: static rtx find_addr_reg ();
                     29: 
                     30: #if 0
                     31: char *
                     32: output_compare (operands, opcode, exchange_opcode)
                     33:      rtx *operands;
                     34:      char *opcode;
                     35:      char *exchange_opcode;
                     36: {
                     37:   static char buf[40];
                     38:   rtx op1, op2;
                     39: 
1.1.1.4 ! root       40:   if (GET_CODE (cc_prev_status.value2) == COMPARE)
1.1       root       41:     {
                     42:       op1 = XEXP (cc_prev_status.value2, 0);
                     43:       op2 = XEXP (cc_prev_status.value2, 1);
                     44:     }
                     45:   else
                     46:     {
                     47:       op1 = cc_prev_status.value2;
                     48:       op2 = const0_rtx;
                     49:     }
                     50:   if (GET_CODE (op1) == CONST_INT)
                     51:     {
                     52:       operands[2] = op1;
                     53:       operands[1] = op2;
                     54:       opcode = exchange_opcode;
                     55:     }
                     56:   else
                     57:     {
                     58:       operands[1] = op1;
                     59:       operands[2] = op2;
                     60:     }
                     61:   sprintf (buf, "cmp r25,%%1,%%2\n\tbcnd %s,r25,%%l0", opcode);
                     62:   return buf;
                     63: }
                     64: 
                     65: char *
                     66: output_fcompare (operands, opcode, exchange_opcode)
                     67:      rtx *operands;
                     68:      char *opcode;
                     69:      char *exchange_opcode;
                     70: {
                     71:   static char buf[40];
                     72: 
                     73:   rtx op1, op2;
                     74: 
1.1.1.4 ! root       75:   if (GET_CODE (cc_prev_status.value2) == COMPARE)
1.1       root       76:     {
                     77:       op1 = XEXP (cc_prev_status.value2, 0);
                     78:       op2 = XEXP (cc_prev_status.value2, 1);
                     79:     }
                     80:   else
                     81:     {
                     82:       op1 = cc_prev_status.value2;
                     83:       op2 = const0_rtx;
                     84:     }
                     85:   if (GET_CODE (op1) == CONST_DOUBLE)
                     86:     {
                     87:       operands[2] = op1;
                     88:       operands[1] = op2;
                     89:       opcode = exchange_opcode;
                     90:     }
                     91:   else
                     92:     {
                     93:       operands[1] = op1;
                     94:       operands[2] = op2;
                     95:     }
                     96:   sprintf (buf, "cmp r25,%%1,%%2\n\tbcnd %s,r25,%%l0", opcode);
                     97:   return buf;
                     98: }
                     99: 
                    100: char *
                    101: output_store (operands, opcode, exchange_opcode)
                    102:      rtx *operands;
                    103:      char *opcode;
                    104:      char *exchange_opcode;
                    105: {
                    106:   static char buf[40];
                    107:   rtx op1, op2;
                    108: 
1.1.1.4 ! root      109:   if (GET_CODE (cc_prev_status.value2) == COMPARE)
1.1       root      110:     {
                    111:       op1 = XEXP (cc_prev_status.value2, 0);
                    112:       op2 = XEXP (cc_prev_status.value2, 1);
                    113:     }
                    114:   else
                    115:     {
                    116:       op1 = cc_prev_status.value2;
                    117:       op2 = const0_rtx;
                    118:     }
                    119: 
                    120:   if (GET_CODE (op1) == CONST_INT)
                    121:     {
                    122:       operands[2] = op1;
                    123:       operands[1] = op2;
                    124:       opcode = exchange_opcode;
                    125:     }
                    126:   else
                    127:     {
                    128:       operands[1] = op1;
                    129:       operands[2] = op2;
                    130:     }
                    131: 
                    132:   sprintf (buf, "cmp r25,%%1,%%2\n\textu %%0,r25,1<%s>", opcode);
                    133:   return buf;
                    134: }
                    135: #endif
                    136: 
                    137: /* Nonzero if OP is a valid second operand for an arithmetic insn.  */
                    138: 
                    139: int
                    140: arith_operand (op, mode)
                    141:      rtx op;
                    142:      enum machine_mode mode;
                    143: {
                    144:   return (register_operand (op, mode)
                    145:          || (GET_CODE (op) == CONST_INT
                    146:              && (unsigned) INTVAL (op) < 0x10000));
                    147: }
                    148: 
                    149: int
                    150: arith32_operand (op, mode)
                    151:      rtx op;
                    152:      enum machine_mode mode;
                    153: {
                    154:   return (register_operand (op, mode) || GET_CODE (op) == CONST_INT);
                    155: }
                    156: 
                    157: int
                    158: int5_operand (op, mode)
                    159:      rtx op;
                    160:      enum machine_mode mode;
                    161: {
                    162:   return (GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x20);
                    163: }
                    164: 
                    165: /* Return the best assembler insn template
                    166:    for moving operands[1] into operands[0] as a fullword.  */
                    167: 
                    168: static char *
                    169: singlemove_string (operands)
                    170:      rtx *operands;
                    171: {
                    172:   if (GET_CODE (operands[0]) == MEM)
                    173:     return "st %r1,%0";
                    174:   if (GET_CODE (operands[1]) == MEM)
                    175:     return "ld %0,%1";
                    176:   return "or %0,r0,%1";
                    177: }
                    178: 
                    179: /* Output assembler code to perform a doubleword move insn
                    180:    with operands OPERANDS.  */
                    181: 
                    182: char *
                    183: output_move_double (operands)
                    184:      rtx *operands;
                    185: {
                    186:   enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
                    187:   rtx latehalf[2];
                    188:   rtx addreg0 = 0, addreg1 = 0;
                    189: 
                    190:   /* First classify both operands.  */
                    191: 
                    192:   if (REG_P (operands[0]))
                    193:     optype0 = REGOP;
                    194:   else if (offsetable_memref_p (operands[0]))
                    195:     optype0 = OFFSOP;
                    196:   else if (GET_CODE (operands[0]) == MEM)
                    197:     optype0 = MEMOP;
                    198:   else
                    199:     optype0 = RNDOP;
                    200: 
                    201:   if (REG_P (operands[1]))
                    202:     optype1 = REGOP;
                    203:   else if (CONSTANT_P (operands[1])
                    204:           || GET_CODE (operands[1]) == CONST_DOUBLE)
                    205:     optype1 = CNSTOP;
                    206:   else if (offsetable_memref_p (operands[1]))
                    207:     optype1 = OFFSOP;
                    208:   else if (GET_CODE (operands[1]) == MEM)
1.1.1.2   root      209:     optype1 = MEMOP;
1.1       root      210:   else
                    211:     optype1 = RNDOP;
                    212: 
                    213:   /* Check for the cases that the operand constraints are not
                    214:      supposed to allow to happen.  Abort if we get one,
                    215:      because generating code for these cases is painful.  */
                    216: 
                    217:   if (optype0 == RNDOP || optype1 == RNDOP)
                    218:     abort ();
                    219: 
                    220:   /* If an operand is an unoffsettable memory ref, find a register
                    221:      we can increment temporarily to make it refer to the second word.  */
                    222: 
                    223:   if (optype0 == MEMOP)
                    224:     addreg0 = find_addr_reg (operands[0]);
                    225: 
                    226:   if (optype1 == MEMOP)
                    227:     addreg1 = find_addr_reg (operands[1]);
                    228: 
                    229:   /* Ok, we can do one word at a time.
                    230:      Normally we do the low-numbered word first,
                    231:      but if either operand is autodecrementing then we
                    232:      do the high-numbered word first.
                    233: 
                    234:      In either case, set up in LATEHALF the operands to use
                    235:      for the high-numbered word and in some cases alter the
                    236:      operands in OPERANDS to be suitable for the low-numbered word.  */
                    237: 
                    238:   if (optype0 == REGOP)
                    239:     latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
                    240:   else if (optype0 == OFFSOP)
                    241:     latehalf[0] = adj_offsetable_operand (operands[0], 4);
                    242:   else
                    243:     latehalf[0] = operands[0];
                    244: 
                    245:   if (optype1 == REGOP)
                    246:     latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
                    247:   else if (optype1 == OFFSOP)
                    248:     latehalf[1] = adj_offsetable_operand (operands[1], 4);
                    249:   else if (optype1 == CNSTOP)
                    250:     {
                    251:       if (CONSTANT_P (operands[1]))
                    252:        latehalf[1] = const0_rtx;
                    253:       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
                    254:        {
1.1.1.3   root      255:          latehalf[1] = gen_rtx (CONST_INT, VOIDmode,
                    256:                                 CONST_DOUBLE_HIGH (operands[1]));
                    257:          operands[1] = gen_rtx (CONST_INT, VOIDmode,
                    258:                                 CONST_DOUBLE_LOW (operands[1]));
1.1       root      259:        }
                    260:     }
                    261:   else
                    262:     latehalf[1] = operands[1];
                    263: 
                    264:   /* If the first move would clobber the source of the second one,
                    265:      do them in the other order.  This happens only for registers;
                    266:      such overlap can't happen in memory unless the user explicitly
                    267:      sets it up, and that is an undefined circumstance.  */
                    268: 
                    269:   if (optype0 == REGOP && optype1 == REGOP
                    270:       && REGNO (operands[0]) == REGNO (latehalf[1]))
                    271:     {
                    272:       /* Make any unoffsetable addresses point at high-numbered word.  */
                    273:       if (addreg0)
                    274:        output_asm_insn ("addu %0,%0,4", &addreg0);
                    275:       if (addreg1)
                    276:        output_asm_insn ("addu %0,%0,4", &addreg1);
                    277: 
                    278:       /* Do that word.  */
                    279:       output_asm_insn (singlemove_string (latehalf), latehalf);
                    280: 
                    281:       /* Undo the adds we just did.  */
                    282:       if (addreg0)
                    283:        output_asm_insn ("subu %0,%0,4", &addreg0);
                    284:       if (addreg1)
                    285:        output_asm_insn ("subu %0,%0,4", &addreg0);
                    286: 
                    287:       /* Do low-numbered word.  */
                    288:       return singlemove_string (operands);
                    289:     }
                    290: 
                    291:   /* Normal case: do the two words, low-numbered first.  */
                    292: 
                    293:   output_asm_insn (singlemove_string (operands), operands);
                    294: 
                    295:   /* Make any unoffsetable addresses point at high-numbered word.  */
                    296:   if (addreg0)
                    297:     output_asm_insn ("addu %0,%0,4", &addreg0);
                    298:   if (addreg1)
                    299:     output_asm_insn ("addu %0,%0,4", &addreg1);
                    300: 
                    301:   /* Do that word.  */
                    302:   output_asm_insn (singlemove_string (latehalf), latehalf);
                    303: 
                    304:   /* Undo the adds we just did.  */
                    305:   if (addreg0)
                    306:     output_asm_insn ("subu %0,%0,4", &addreg0);
                    307:   if (addreg1)
                    308:     output_asm_insn ("subu %0,%0,4", &addreg1);
                    309: 
                    310:   return "";
                    311: }
                    312: 
                    313: /* Return a REG that occurs in ADDR with coefficient 1.
                    314:    ADDR can be effectively incremented by incrementing REG.  */
                    315: 
                    316: static rtx
                    317: find_addr_reg (addr)
                    318:      rtx addr;
                    319: {
                    320:   while (GET_CODE (addr) == PLUS)
                    321:     {
                    322:       if (GET_CODE (XEXP (addr, 0)) == REG)
                    323:        addr = XEXP (addr, 0);
                    324:       if (GET_CODE (XEXP (addr, 1)) == REG)
                    325:        addr = XEXP (addr, 1);
                    326:       if (CONSTANT_P (XEXP (addr, 0)))
                    327:        addr = XEXP (addr, 1);
                    328:       if (CONSTANT_P (XEXP (addr, 1)))
                    329:        addr = XEXP (addr, 0);
                    330:     }
                    331:   if (GET_CODE (addr) == REG)
                    332:     return addr;
                    333:   return 0;
                    334: }
                    335: 
                    336: /* Output an ascii string.  */
                    337: output_ascii (file, p, size)
                    338:      FILE *file;
                    339:      char *p;
                    340:      int size;
                    341: {
                    342:   int i;
                    343: 
                    344:   fprintf (file, "\tstring \"");
                    345: 
                    346:   for (i = 0; i < size; i++)
                    347:     {
                    348:       register int c = p[i];
                    349:       if (c == '\"' || c == '\\')
                    350:        putc ('\\', file);
                    351:       if (c >= ' ' && c < 0177)
                    352:        putc (c, file);
                    353:       else
                    354:        {
                    355:          fprintf (file, "\\%03o", c);
                    356:          /* After an octal-escape, if a digit follows,
                    357:             terminate one string constant and start another.
                    358:             The Vax assembler fails to stop reading the escape
                    359:             after three digits, so this is the only way we
                    360:             can get it to parse the data properly.  */
                    361:          if (i < size - 1 && p[i + 1] >= '0' && p[i + 1] <= '9')
                    362:            fprintf (file, "\"\n\tstring \"");
                    363:        }
                    364:     }
                    365:   fprintf (file, "\"\n");
                    366: }
                    367: 
                    368: void
                    369: output_load_address (operands)
                    370:      rtx *operands;
                    371: {
                    372:   rtx base, offset;
                    373: 
                    374:   if (CONSTANT_P (operands[3]))
                    375:     {
                    376:       output_asm_insn ("lda %0,%3", operands);
                    377:       return;
                    378:     }
                    379: 
                    380:   if (REG_P (operands[3]))
                    381:     {
                    382:       if (REGNO (operands[0]) != REGNO (operands[3]))
                    383:        output_asm_insn ("or %0,r0,%3", operands);
                    384:       return;
                    385:     }
                    386: 
                    387:   base = XEXP (operands[3], 0);
                    388:   offset = XEXP (operands[3], 1);
                    389: 
                    390:   if (GET_CODE (base) == CONST_INT)
                    391:     {
                    392:       rtx tmp = base;
                    393:       base = offset;
                    394:       offset = tmp;
                    395:     }
                    396: 
                    397:   if (GET_CODE (offset) != CONST_INT)
                    398:     abort ();
                    399: 
                    400:   operands[6] = base;
                    401:   operands[7] = offset;
                    402: 
                    403:   if (REG_P (base))
                    404:     if (FITS_16_BITS (offset))
                    405:       output_asm_insn ("addu %0,%6,%7", operands);
                    406:     else if (INT_FITS_16_BITS (- INTVAL (offset)))
                    407:       output_asm_insn ("subu %0,%6,%7", operands);
                    408:     else
                    409:       output_asm_insn ("or.h %0,r0,hi16(%7)\n\tor %0,%0,lo16(%7)\n\tadd %0,%6,%0", operands);
                    410:   else
                    411:     {
                    412:       if (GET_CODE (base) == MULT)
                    413:        if (GET_MODE (base) == QImode)
                    414:          output_asm_insn ("lda.b %0,%6");
                    415:        else if (GET_MODE (base) == HImode)
                    416:          output_asm_insn ("lda.h %0,%6");
                    417:        else if (GET_MODE (base) == SImode)
                    418:          output_asm_insn ("lda %0,%6");
                    419:        else
                    420:          output_asm_insn ("lda.d %0,%6");
                    421:       else
                    422:        output_asm_insn ("lda %0,%6");
                    423: 
                    424:       if (FITS_16_BITS (offset))
                    425:        output_asm_insn ("addu %0,%7,%0", operands);
                    426:       else if (INT_FITS_16_BITS (- INTVAL (offset)))
                    427:        output_asm_insn ("subu %0,%7,%0", operands);
                    428:       else
                    429:        output_asm_insn ("or.h r25,r0,hi16(%7)\n\tor r25,r0,lo16(%7)\n\taddu %0,%0r25", operands);
                    430:     }
                    431: }
                    432: 
                    433: char *
                    434: output_block_move (operands)
                    435:      rtx *operands;
                    436: {
                    437:   static int movstrsi_label = 0;
                    438:   int align = 4;
                    439: 
                    440:   rtx xoperands[9];
                    441:   int available[3];
                    442:   int i, j;
                    443: 
                    444:   /* Since we clobber untold things, nix the condition codes.  */
                    445:   CC_STATUS_INIT;
                    446: 
                    447:   /* Get past the MEMs.  */
                    448:   operands[0] = XEXP (operands[0], 0);
                    449:   operands[1] = XEXP (operands[1], 0);
                    450: 
                    451:   xoperands[0] = 0;
                    452:   xoperands[1] = 0;
                    453:   xoperands[2] = 0;
                    454: 
                    455:   available[0] = 1;
                    456:   available[1] = 1;
                    457:   available[2] = 1;
                    458: #if 1
                    459:   /* Prepare to juggle registers if necessary.  */
                    460:   if (REG_P (operands[0]) && (unsigned) (REGNO (operands[0]) - 10) < 3)
                    461:     {
                    462:       xoperands[0] = operands[0];
                    463:       available[REGNO (operands[0]) - 10] = 0;
                    464:     }
                    465:   if (REG_P (operands[1]) && (unsigned) (REGNO (operands[1]) - 10) < 3)
                    466:     {
                    467:       xoperands[1] = operands[1];
                    468:       available[REGNO (operands[1]) - 10] = 0;
                    469:     }
                    470:   if (REG_P (operands[2]) && (unsigned) (REGNO (operands[2]) - 10) < 3)
                    471:     {
                    472:       xoperands[2] = operands[2];
                    473:       available[REGNO (operands[2]) - 10] = 0;
                    474:     }
                    475:   for (i = 0; i < 3; i++)
                    476:     {
                    477:       if (xoperands[i])
                    478:        continue;
                    479:       if (available[0])
                    480:        {
                    481:          xoperands[i] = gen_rtx (REG, SImode, 10);
                    482:          available[0] = 0;
                    483:          continue;
                    484:        }
                    485:       if (available[1])
                    486:        {
                    487:          xoperands[i] = gen_rtx (REG, SImode, 11);
                    488:          available[1] = 0;
                    489:          continue;
                    490:        }
                    491:       xoperands[i] = gen_rtx (REG, SImode, 12);
                    492:       available[2] = 0;
                    493:     }
                    494: #endif
                    495: 
                    496:   /* First, figure out best alignment we may assume.  */
                    497:   if (REG_P (operands[2]))
                    498:     {
                    499:       xoperands[5] = operands[2];
                    500:       output_asm_insn ("sub %5,%2,1", xoperands);
                    501:       align = 1;
                    502:     }
                    503:   else
                    504:     {
                    505:       int i = INTVAL (operands[2]);
                    506: 
                    507:       if (i & 1)
                    508:        align = 1;
                    509:       else if (i & 3)
                    510:        {
                    511:          align = 2;
                    512:          i >>= 1;
                    513:        }
                    514:       else
                    515:        i >>= 2;
                    516: 
                    517:       /* predecrement count.  */
                    518:       i -= 1;
                    519:       if (i < 0) abort ();
                    520: 
                    521:       xoperands[5] = gen_rtx (CONST_INT, VOIDmode, i);
                    522: 
                    523:       if (INT_FITS_16_BITS (i))
                    524:        output_asm_insn ("addu %2,r0,%5", xoperands);
                    525:       else if (INT_FITS_16_BITS (-i))
                    526:        {
                    527:          xoperands[5] = gen_rtx (CONST_INT, VOIDmode, -i);
                    528:          output_asm_insn ("subu %2,r0,%5", xoperands);
                    529:        }
                    530:       else
                    531:        output_asm_insn ("or.u %2,r0,hi16(%5)\n\tor %2,%2,lo16(%5)", xoperands);
                    532:     }
                    533:   /* Now, set up for pipelined operation: dest must contain
                    534:      a pre-incremented address, because its index is pre-decremented.  */
                    535: 
                    536:   xoperands[3] = plus_constant (operands[0], align);
                    537:   output_load_address (xoperands);
                    538: 
                    539:   xoperands[4] = operands[1];
                    540:   output_load_address (xoperands+1);
                    541: 
                    542:   xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++);
                    543: 
                    544:   if (align == 4)
                    545:     output_asm_insn ("\n@Lm%3:\n\tld r25,%1[%2]\n\tsubu %2,%2,1\n\tbcnd.n ge0,%2,@Lm%3\n\tst r25,%0[%2]", xoperands);
                    546:   else if (align == 2)
                    547:     output_asm_insn ("\n@Lm%3:\n\tld.h r25,%1[%2]\n\tsubu %2,%2,1\n\tbcnd.n ge0,%2,@Lm%3\n\tst.h r25,%0[%2]", xoperands);
                    548:   else
                    549:     output_asm_insn ("\n@Lm%3:\n\tld.b r25,%1[%2]\n\tsubu %2,%2,1\n\tbcnd.n ge0,%2,@Lm%3\n\tst.b r25,%0[%2]", xoperands);
                    550:   return "";
                    551: }
                    552: 
                    553: char *
                    554: output_store_const_int (mode, operands)
                    555:      enum machine_mode mode;
                    556:      rtx *operands;
                    557: {
                    558:   int i = INTVAL (operands[1]);
                    559:   if (INT_FITS_16_BITS (i))
                    560:     return "addu %0,r0,%1";
                    561:   if (INT_FITS_16_BITS (-i))
                    562:     {
                    563:       operands[1] = gen_rtx (CONST_INT, VOIDmode, -i);
                    564:       return "subu %0,r0,%1";
                    565:     }
                    566:   if ((i & 0xffff) == 0)
                    567:     return "or.u %0,r0,hi16(%1)";
                    568:   /* Could check to see if number is a contiguous field
                    569:      of 1's.  Then we could use the SET instruction.  */
                    570:   if (mode == HImode)
                    571:     {
                    572:       warning ("truncating constant `%d' to fit in half-word", INTVAL (operands[1]));
                    573:       return "or %0,r0,lo16(%1)";
                    574:     }
                    575:   if (mode == QImode)
                    576:     {
                    577:       warning ("truncating constant `%d' to fit in byte");
                    578:       operands[1] = gen_rtx (CONST_INT, VOIDmode, i & 0xff);
                    579:       return "or %0,r0,%1";
                    580:     }
                    581: 
                    582:   return "or.u %0,r0,hi16(%1)\n\tor %0,%0,lo16(%1)";
                    583: }
                    584: 
                    585: /* This routine assumes that floating point numbers are represented
                    586:    in a manner which is consistent between host and target machines.  */
                    587: char *
                    588: output_store_const_float (mode, operands)
                    589:      enum machine_mode mode;
                    590:      rtx *operands;
                    591: {
                    592:   int i = INTVAL (operands[1]);
                    593:   if (INT_FITS_16_BITS (i))
                    594:     return "addu %0,r0,%1";
                    595:   if (INT_FITS_16_BITS (-i))
                    596:     {
                    597:       operands[1] = gen_rtx (CONST_INT, VOIDmode, -i);
                    598:       return "subu %0,r0,%1";
                    599:     }
                    600:   if ((i & 0xffff) == 0)
                    601:     return "or.u %0,r0,hi16(%1)";
                    602:   /* Could check to see if number is a contiguous field
                    603:      of 1's.  Then we could use the SET instruction.  */
                    604:   return "or.u %0,r0,hi16(%1)\n\tor %0,%0,lo16(%1)";
                    605: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.