Annotation of researchv9/cmd/sun/as/coprocessor.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static  char sccsid[] = "@(#)coprocessor.c 1.1 86/02/03 Copyr 1985 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include "as.h"
                     10: 
                     11: cp_general( ip )
                     12:        struct ins_bkt *ip ;
                     13: 
                     14: {
                     15: struct oper *op1, *op2 ;
                     16: unsigned r1, r2 ;
                     17: 
                     18: /*
                     19:        opval_i[0] -- fop ea,fpn
                     20:        opval_i[1] -- fop fpm,fpn
                     21: */
                     22: 
                     23: op1 = &operands[0] ;
                     24: op2 = &operands[1] ;
                     25: r2 = (int) op2 -> value_o - FP0REG ;
                     26: code_length = 4 ;
                     27: wcode[0] = 0xf000 + current_cpid * 01000 ;
                     28: 
                     29: if (freg_addr(op1))
                     30:        {
                     31:        r1 = (int) op1 -> value_o - FP0REG ;
                     32:        wcode[1] = ip->opval_i[1] + r2 * 0200 + r1 * 02000 ;
                     33:        }
                     34: else
                     35:        {
                     36:        wcode[1] = ip->opval_i[0] + r2 * 0200 ;
                     37:        eaddr( op1, ip->subop_i, 0) ;
                     38:        }
                     39: }
                     40: 
                     41: cp_oneop( ip )
                     42:        struct ins_bkt *ip ;
                     43: 
                     44: {
                     45: struct oper *op1;
                     46: unsigned r1;
                     47: 
                     48: /*
                     49:        opval_i[0] -- fop ea
                     50:        opval_i[1] -- fop fpm
                     51: */
                     52: 
                     53: op1 = &operands[0] ;
                     54: code_length = 4 ;
                     55: wcode[0] = 0xf000 + current_cpid * 01000 ;
                     56: 
                     57: if (freg_addr(op1))
                     58:        {
                     59:        r1 = (int) op1 -> value_o - FP0REG ;
                     60:        wcode[1] = ip->opval_i[1] + r1 * 02000 ;
                     61:        }
                     62: else
                     63:        {
                     64:        wcode[1] = ip->opval_i[0] ;
                     65:        eaddr( op1, ip->subop_i, 0) ;
                     66:        }
                     67: }
                     68: 
                     69: cp_move( ip )
                     70:        struct ins_bkt *ip ;
                     71: 
                     72: {
                     73: struct oper *op1, *op2 ;
                     74: unsigned r1, r2 ;
                     75: 
                     76: /*
                     77:        opval_i[0] -- fmov? ea,fpn
                     78:        opval_i[1] -- fmov? fpm,ea
                     79:        opval_i[2] -- fmovx fpm,fpn
                     80:                   -- fmovl ea,fpctrl
                     81:        opval_i[3] -- fmovl fpctrl,ea
                     82: 
                     83: */
                     84: 
                     85: op1 = &operands[0] ;
                     86: op2 = &operands[1] ;
                     87: r1 = (int) op1 -> value_o - FP0REG ;
                     88: r2 = (int) op2 -> value_o - FP0REG ;
                     89: code_length = 4 ;
                     90: wcode[0] = 0xf000 + current_cpid * 01000 ;
                     91: 
                     92: if (freg_addr(op1)) 
                     93: {
                     94: if (freg_addr(op2))
                     95:        { /* fmovx fpm,fpn */ 
                     96:        wcode[1] = ip->opval_i[2] + r1 * 02000 + r2 * 0200 ;
                     97:        }
                     98: else
                     99:        { /* fmov? fpm,ea */
                    100:        wcode[1] = ip->opval_i[1] + r1 * 0200 ;
                    101:        eaddr( op2, ip->subop_i, 1) ;
                    102:        }
                    103: }
                    104: else
                    105:        if (freg_addr(op2))
                    106:                { /* fmov? ea,fpn */
                    107:                wcode[1] = ip->opval_i[0] + r2 * 0200 ;
                    108:                eaddr( op1, ip->subop_i, 0) ;
                    109:                }
                    110:        else 
                    111:        {
                    112:        if (fctrlreg_addr(op2))
                    113:                { /* fmovl ea,fpctrl */
                    114:                switch((int) op2->value_o)
                    115:                        {
                    116:                        case FPCREG: { r2 = 4 ; break ; }
                    117:                        case FPSREG: { r2 = 2 ; break ; }
                    118:                        case FPIREG: { r2 = 1 ; break ; }
                    119:                        }
                    120:                wcode[1] = ip->opval_i[2] + r2 * 02000 ;
                    121:                eaddr( op1, ip->subop_i, 0) ;
                    122:                }
                    123:        else
                    124:                { /* fmovl fpctrl,ea */
                    125:                switch((int) op1->value_o)
                    126:                        {
                    127:                        case FPCREG: { r2 = 4 ; break ; }
                    128:                        case FPSREG: { r2 = 2 ; break ; }
                    129:                        case FPIREG: { r2 = 1 ; break ; }
                    130:                        }
                    131:                wcode[1] = ip->opval_i[3] + r2 * 02000 ;
                    132:                eaddr( op2, ip->subop_i, 0) ;
                    133:                }
                    134:        }
                    135: }
                    136: 
                    137: cp_regpair( ip )
                    138:        struct ins_bkt *ip ;
                    139: 
                    140: /* Works like cp_general except the result is put in a PAIR
                    141:  * of fp registers. 
                    142:  */
                    143: 
                    144: {
                    145: struct oper *op1, *op2 ;
                    146: unsigned r1, r2, r3 ;
                    147: 
                    148: /*
                    149:        opval_i[0] -- fop ea,fpn:fpq
                    150:        opval_i[1] -- fop fpm,fpn:fpq
                    151: */
                    152: 
                    153: op1 = &operands[0] ;
                    154: op2 = &operands[1] ;
                    155: r2 = (int) op2 -> reg_o - FP0REG ;
                    156: r3 = (int) op2 -> value_o - FP0REG ;
                    157: code_length = 4 ;
                    158: wcode[0] = 0xf000 + current_cpid * 01000 ;
                    159: 
                    160: if (freg_addr(op1))
                    161:        {
                    162:        r1 = (int) op1 -> value_o - FP0REG ;
                    163:        wcode[1] = ip->opval_i[1] + r2 * 0200 + r1 * 02000 + r3 ;
                    164:        }
                    165: else
                    166:        {
                    167:        wcode[1] = ip->opval_i[0] + r2 * 0200 + r3 ;
                    168:        eaddr( op1, ip->subop_i, 0) ;
                    169:        }
                    170: }
                    171: 
                    172: cp_movecr( ip )
                    173:        struct ins_bkt *ip ;
                    174: 
                    175: /*
                    176: 
                    177:        For general format coprocessor instructions that put an immediate
                    178:        operand in the op code extension field.
                    179: 
                    180: */
                    181: 
                    182: {
                    183: struct oper *op1, *op2 ;
                    184: unsigned r1, r2 ;
                    185: 
                    186: /*
                    187:        opval_i[0] -- fop #ccc,fpn
                    188: */
                    189: 
                    190: op1 = &operands[0] ;
                    191: op2 = &operands[1] ;
                    192: r2 = (int) op2 -> value_o - FP0REG ;
                    193: code_length = 4 ;
                    194: wcode[0] = 0xf000 + current_cpid * 01000 ;
                    195: wcode[1] = ip->opval_i[0] + r2 * 0200 + op1->value_o ;
                    196: }
                    197: 
                    198: 
                    199: int reverse_8bits( forward )
                    200:         int forward ;
                    201: 
                    202: /*
                    203:         result = forward with with 8 low order bits in reverse order.
                    204: */
                    205:  
                    206: {
                    207: int bit, new ;
                    208: long i ;
                    209: 
                    210: new = 0 ;
                    211: bit = 0x80 ;
                    212: 
                    213: for (i=0 ; i<8 ; i++ )
                    214:         {
                    215:         if (forward & 1) new |= bit ;
                    216:         forward = forward >> 1 ;
                    217:         bit = bit >> 1 ;
                    218:         }
                    219: return(new) ;
                    220: }
                    221:  
                    222: cp_movem( ip )
                    223:        struct ins_bkt *ip ;
                    224: 
                    225: /*
                    226: 
                    227:        Floating move multiples come in too many varieties:
                    228: 
                    229:        fmovem  ea,#imm
                    230:        fmovem  ea,freglist
                    231:        fmovem  ea,dn
                    232:        fmovem  ea,fcreglist
                    233:        fmovem  #imm,ea
                    234:        fmovem  #imm,sp@-
                    235:        fmovem  freglist,ea
                    236:        fmovem  freglist,sp@-
                    237:        fmovem  dn,ea
                    238:        fmovem  dn,sp@-
                    239:        fmovem  fcreglist,ea
                    240: 
                    241: */
                    242: 
                    243: {
                    244: struct oper *op1, *op2 ;
                    245: 
                    246: /*
                    247:        opval_i[0] -- fmovem    ea,#imm or freglist or dn
                    248:        opval_i[1] -- fmovem    ...,ea
                    249:        opval-i[2] -- fmovem    ea,fcreglist
                    250:        opval-i[3] -- fop       fcreglist,ea
                    251: */
                    252: 
                    253: op1 = &operands[0] ;
                    254: op2 = &operands[1] ;
                    255: code_length = 4 ;
                    256: wcode[0] = 0xf000 + current_cpid * 01000 ;
                    257: switch (op2->type_o)
                    258: {
                    259:        case T_FCREGLIST:/*     fmovem  ea,fcreglist    */
                    260:                {
                    261:                wcode[1] = ip->opval_i[2] + op2->value_o * 0x400 ;
                    262:                eaddr( op1, ip->subop_i, 0) ;
                    263:                break ;
                    264:                }
                    265:        case T_IMMED:   /*      fmovem  ea,#imm */
                    266:                {
                    267:                wcode[1] = ip->opval_i[0] + op2->value_o ;
                    268:                eaddr( op1, ip->subop_i, 0) ;
                    269:                break ;
                    270:                }
                    271:        case T_FREGLIST:/*      fmovem  ea,freglist     */
                    272:                {
                    273:                wcode[1] = ip->opval_i[0] + reverse_8bits(op2->value_o) ;
                    274:                eaddr( op1, ip->subop_i, 0) ;
                    275:                break ;
                    276:                }
                    277:        case T_REG:     /*      fmovem  ea,dn   */
                    278:                {
                    279:                wcode[1] = ip->opval_i[0] + 0x800 + (op2->value_o-D0REG)*0x10;
                    280:                eaddr( op1, ip->subop_i, 0) ;
                    281:                break ;
                    282:                }
                    283: default: 
                    284:        {
                    285:        switch(op1->type_o)
                    286:        {
                    287:        case T_FCREGLIST:/*     fmovem  fcreglist,ea    */
                    288:                {
                    289:                wcode[1] = ip->opval_i[3] + op1->value_o * 0x400 ;
                    290:                break ;
                    291:                }
                    292:        case T_IMMED:   /*      fmovem  #imm,ea */
                    293:                {
                    294:                wcode[1] = ip->opval_i[1] + op1->value_o ;
                    295:                if (op2->type_o != T_PREDEC) wcode[1] |= 0x1000 ; 
                    296:                break ;
                    297:                }
                    298:        case T_FREGLIST:/*      fmovem  freglist,ea     */
                    299:                {
                    300:                wcode[1] = ip->opval_i[1] ;
                    301:                if (op2->type_o == T_PREDEC) 
                    302:                        wcode[1] |= op1->value_o ;
                    303:                else
                    304:                        wcode[1] |= 0x1000 | reverse_8bits(op1->value_o); 
                    305:                break ;
                    306:                }
                    307:        case T_REG:     /*      fmovem  dn,ea   */
                    308:                {
                    309:                wcode[1] = ip->opval_i[1] + 0x800 + (op1->value_o-D0REG)*0x10;
                    310:                if (op2->type_o != T_PREDEC) wcode[1] |= 0x1000 ; 
                    311:                break ;
                    312:                }
                    313:        }
                    314:        eaddr( op2, ip->subop_i, 1) ;
                    315:        }
                    316: }
                    317: }
                    318: 
                    319: cp_oneword( ip )
                    320:        struct ins_bkt *ip ;
                    321: 
                    322: /* For one word coprocessor instructions like FSAVE and FRESTORE. */
                    323: 
                    324: {
                    325: struct oper *op1 ;
                    326: 
                    327: /*
                    328:        opval_i[0] -- fop ea
                    329: */
                    330: 
                    331: op1 = &operands[0] ;
                    332: wcode[0] = ip->opval_i[0] + current_cpid * 01000 ;
                    333: eaddr( op1, ip->subop_i, 0) ;
                    334:        
                    335: }
                    336: 
                    337: cp_branch( ip )
                    338:        struct ins_bkt *ip ;
                    339: 
                    340: /*     For coprocessor 16, 32, and indeterminate branches.     */
                    341: 
                    342: {
                    343:         long offs = 0;
                    344:         register struct oper *opp = operands;
                    345:        int offlong, instlong ;
                    346:        int useshort;
                    347:  
                    348:         wcode[0] = ip->opval_i[0] + current_cpid * 01000 ;
                    349:         if (ip->noper_i == 0) 
                    350:                { /* fnop */
                    351:                code_length = 4 ;
                    352:                wcode[1] = 0 ;
                    353:                return ;        
                    354:                }
                    355:         offs = opp->value_o - (dot + 2);
                    356:        if (hflag )
                    357:           useshort = 1;
                    358:        else
                    359:           useshort = d2flag||jsrflag;
                    360:         if (opp->flags_o & O_COMPLEX) {
                    361:            /* not a simple address  */
                    362:            opp->value_o = (int) offs;
                    363:            rel_val(opp, SUBOP_W, opp->sym_o != 0);
                    364:            return;
                    365:         }
                    366:         if (pass == 1 ) {
                    367:           if (cansdi) 
                    368:                code_length += useshort? 2 : makesdi(opp, dot+2, SDIP);
                    369:          else
                    370:               code_length += (useshort)?2:4;
                    371:           put_rel(opp, SUBOP_L, dot+2, 0);
                    372:         }
                    373:         else {
                    374:            /* pass 2 */
                    375:          if ( opp->sym_o && (opp->sym_o->attr_s & S_DEF) == 0){
                    376:                 /* external branch -- good luck */
                    377:                 ;
                    378:           } else if (opp->sym_o == 0 || opp->sym_o->csect_s != cur_csect_name){
                    379:                 PROG_ERROR(E_RELOCATE);
                    380:           } else {
                    381:                opp->sym_o = 0; /* mark as non relocateable expression */
                    382:           }
                    383:           offlong = (offs > 32767L || offs < -32768L) ;
                    384:           if (ip->opval_i[0] & 0100)      instlong = 1 ; /* fbccl*/ 
                    385:          else if (ip->opval_i[0] & 0200) instlong = 0 ;  /* fbcc  */
                    386:               else                             
                    387:                  { /* fjcc */
                    388:                     instlong = offlong ;
                    389:                      if (instlong && !useshort )       
                    390:                        wcode[0] |= 0300 ; /* Op code for fbccl.  */ 
                    391:                     else  
                    392:                         wcode[0] |= 0200 ; /* Op code for fbcc . */
                    393:                  }
                    394:          if (offlong &~ instlong) PROG_ERROR(E_OFFSET); 
                    395:           opp->value_o = (int)offs; 
                    396:           if (instlong && !useshort) 
                    397:             rel_val(opp, SUBOP_L, opp->sym_o != 0);
                    398:          else 
                    399:              rel_val(opp, SUBOP_W, opp->sym_o != 0);
                    400:         }
                    401: }
                    402: 
                    403: cp_conditional ( ip )
                    404:        struct ins_bkt *ip ;
                    405: /*
                    406: 
                    407:        Coprocessor conditional instructions:
                    408:                fscc    ea
                    409:                fdbcc   dn,label
                    410:                ftcc
                    411:                ftccw   #imm
                    412:                ftccl   #imm
                    413: 
                    414: */
                    415: 
                    416: {
                    417: struct oper *op1, *op2 ;
                    418: long offs = 0;
                    419: 
                    420: /*
                    421:        opval_i[0] -- fop ea,fpn
                    422:        opval_i[1] -- fop fpm,fpn
                    423: */
                    424: 
                    425: code_length = 4 ;
                    426: wcode[0] = ip->opval_i[0] + current_cpid * 01000 ;
                    427: wcode[1] = ip->opval_i[1] ;            /* condition code */
                    428: switch(ip->noper_i)
                    429:        {
                    430:        /* case 0: ftcc - nothing more to do */
                    431:        case 1: {
                    432:                op1 = &operands[0] ;
                    433:                if (op1->type_o == T_IMMED)
                    434:                        { /* ftccw or ftccl */
                    435:                        rel_val(op1, ip->subop_i, 0) ;
                    436:                        }
                    437:                else
                    438:                        { /* fscc */
                    439:                        eaddr( op1, ip->subop_i, 0) ;
                    440:                        }
                    441:                break ;
                    442:                }
                    443:        case 2: { /* fdbcc */
                    444:                op1 = &operands[0] ;
                    445:                op2 = &operands[1] ;
                    446:                        wcode[0] |= op1->value_o;
                    447:                if ( op2->sym_o && (op2->sym_o->attr_s & S_DEF) == 0){
                    448:                        /* external branch -- good luck */
                    449:                        ;
                    450:                } else if (op2->sym_o == 0 || op2->sym_o->csect_s != cur_csect_name){
                    451:                        PROG_ERROR(E_RELOCATE);
                    452:                } else {
                    453:                        op2->sym_o = 0; /* mark as non relocateable expression */
                    454:                }
                    455:                offs = op2->value_o - (dot + 4);
                    456:                if (offs > 32767L || offs < -32768L)
                    457:                        PROG_ERROR(E_OFFSET);
                    458:                op2->value_o = (int)offs;
                    459:                rel_val(op2, SUBOP_W, op2->sym_o != 0);
                    460:                break ;
                    461:                }
                    462:        } 
                    463: }
                    464: 

unix.superglobalmegacorp.com

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