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

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

unix.superglobalmegacorp.com

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