Annotation of researchv9/cmd/sun/as/instruction.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)instruction.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: #if C2
        !            11: #include "c2.h"
        !            12: #endif
        !            13: 
        !            14: extern char *malloc();
        !            15: struct oper *newoperand();
        !            16: struct oper  operands[OPERANDS_MAX];
        !            17: int numops, code_length;
        !            18: 
        !            19: #if C2
        !            20: NODE first = { OP_FIRST, SUBOP_OTHER, &first, &first };
        !            21: 
        !            22: /* does this branch read the c or v bit of the condition code? */
        !            23: char read_cc_cv[]={ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0 };
        !            24: static struct ins_bkt * moveq = NULL;
        !            25: #endif
        !            26: 
        !            27: instruction( ip )
        !            28:     register struct ins_bkt *ip;
        !            29: {
        !            30: #if C2
        !            31:     register NODE *np;
        !            32: #endif
        !            33:     register i;
        !            34: 
        !            35:     if ((ip->xflags_i&I20) && !ext_instruction_set)
        !            36:        PROG_ERROR( E_OPCODE );
        !            37:     i = 0;
        !            38:     if (ip->noper_i != numops && ip->noper_i <= OPERANDS_MAX){
        !            39:        if ( (ip->touchop_i&TOUCH1(TOUCHMASK)) == TOUCH1(SPEC(2)) && numops==1 && ip->subop_i == SUBOP_W )
        !            40:            /* shifts are a special case...*/
        !            41:            i = 0;
        !            42:        else if ( (ip->touchop_i&TOUCH1(TOUCHMASK)) == TOUCH1(SPEC(6)) && numops==0 )
        !            43:            /* so is rts */
        !            44:            i = 0;
        !            45:        else
        !            46:            i = (E_NUMOPS);
        !            47:     } else switch (ip->noper_i){
        !            48:     default: i = 0; break;
        !            49:     case 1:
        !            50:            i = operand_ok( ip, &operands[0], (struct oper *)NULL, (struct oper *)NULL); break;
        !            51:     case 2:
        !            52:            i = operand_ok( ip, &operands[0], &operands[1], (struct oper *)NULL);break;
        !            53:     case 3:
        !            54:            i = operand_ok( ip, &operands[0], &operands[1], &operands[2] );break;
        !            55:     }
        !            56:     if (i)
        !            57:        PROG_ERROR(i);
        !            58:     if (ip->align_i & dot) /* don't want instructions on odd bounds */
        !            59:            PROG_ERROR(E_ODDADDR);
        !            60: #if AS
        !            61:     if (ISINSTRUC( ip->op_i ) )
        !            62:            code_length = 2; /* all instructions at least this long */
        !            63: #endif
        !            64:     (ip->routine_i)(ip, numops);
        !            65: #if AS
        !            66:     if (code_length) {
        !            67:          put_words(code,code_length);  /* output text */
        !            68:          bc = code_length;             /* increment LC */
        !            69:     }
        !            70: #endif
        !            71: }
        !            72: 
        !            73: 
        !            74: static unsigned
        !            75: op_to_bits( op )
        !            76:     register struct oper *op;
        !            77: {
        !            78:     /* return the address-mode bits for operand *op */
        !            79:     register unsigned s; 
        !            80:     static unsigned bits[] = {
        !            81:        0,
        !            82:        AM_REG, AM_DEFER, AM_POSTINC, AM_PREDEC, AM_DISPL,
        !            83:        AM_INDEX, AM_ABSS, AM_ABSL, AM_IMMED, AM_NORMAL, 
        !            84:        AM_REGPAIR, -1, -1, -1, -1,
        !            85:        AM_REGLIST,AM_FREGLIST,AM_FCREGLIST
        !            86:     };
        !            87:     switch ( s = bits[(int)op->type_o]){
        !            88:     case AM_REG:
        !            89:        s = reg_access[op->value_o]; break;
        !            90:     case AM_DISPL:
        !            91:        if (op->reg_o == PCREG) s = AM_PCDISPL; break;
        !            92:     case AM_INDEX:
        !            93:        if (op->reg_o == PCREG) s = AM_PCINDEX; break;
        !            94:     }
        !            95:     return s;
        !            96: }
        !            97: 
        !            98: int
        !            99: operand_ok( ip, op1, op2, op3 )
        !           100:     struct ins_bkt *ip;
        !           101:     struct oper    *op1, *op2, *op3;
        !           102: {
        !           103:     /*
        !           104:      * this routine answers the eternal question:
        !           105:      *  are operands *op1 and *op2 ok to use as the operands of instruction *ip?
        !           106:      * it does it by looking at the optype_i bit fields in the instruction
        !           107:      * description.
        !           108:      */
        !           109:     register i;
        !           110:     register unsigned opbits1, opbits2, opbits3;
        !           111:     register noperands = ip->noper_i;
        !           112: 
        !           113:     op1->access_o = opbits1 = op_to_bits( op1 );
        !           114:     if (op2)
        !           115:        op2->access_o = opbits2 = op_to_bits( op2 );
        !           116:     else
        !           117:        opbits2 = 0;
        !           118:     if (op3)
        !           119:        op3->access_o = opbits3 = op_to_bits( op3 );
        !           120:     else
        !           121:        opbits3 = 0;
        !           122:     switch (ip->touchop_i&TOUCH2(TOUCHMASK)){
        !           123:     case TOUCH2(SPEC(2)):
        !           124:        /* special hackery for shifts */
        !           125:        if (opbits1 == AM_IMMED && ((i=op1->value_o)<1 || i>8 || op1->sym_o))
        !           126:            return E_CONSTANT;
        !           127:        break;
        !           128:     } 
        !           129:     switch (ip->touchop_i&TOUCH1(TOUCHMASK)){
        !           130:     case TOUCH1(SPEC(0)):
        !           131:     case TOUCH1(SPEC(1)):
        !           132:        /* special hackery for bit ops */
        !           133:        if (opbits1 == AM_IMMED){
        !           134:            i = op1->value_o;
        !           135:            if (op1->sym_o) return E_CONSTANT;
        !           136:            if (opbits2 == AM_DREG){
        !           137:                if (i < 0 || i > 31 ) return E_CONSTANT;
        !           138:            } else 
        !           139:                if (i < 0 || i > 7 ) return E_CONSTANT;
        !           140:        }
        !           141:        break;
        !           142:     }
        !           143:     switch (noperands){
        !           144:     case 0: return 0;
        !           145:     case 1:
        !           146:        for (i=0; i<N_OPTYPES; i+=1)
        !           147:            if (opbits1&ip->optype_i[i]) return 0;
        !           148:        break;
        !           149:     case 2:
        !           150:        for (i=0; i<N_OPTYPES; i+=2)
        !           151:            if ((opbits1&ip->optype_i[i]) && (opbits2&ip->optype_i[i+1]) ) return 0;
        !           152:        break;
        !           153:     case 3:
        !           154:        for (i=0; i<N_OPTYPES; i+=3)
        !           155:            if ((opbits1&ip->optype_i[i]) && (opbits2&ip->optype_i[i+1]) && (opbits3&ip->optype_i[i+2]) ) return 0;
        !           156:        break;
        !           157:     }
        !           158:     return E_OPERAND;
        !           159: }
        !           160: 
        !           161: 
        !           162: /* table used to determine node type. */
        !           163: /* 
        !           164:  * we would really like this table to be subscripted by the enumerated type
        !           165:  * opcode_t, but C cannot hack that. Order here is VERY IMPORTANT,
        !           166:  * and this table must change if the opcode order or number changes!!
        !           167:  */
        !           168: char opcodetypes[] = {
        !           169:        0, 0, 0,                        /* FIRST, COMMENT, LABEL */
        !           170:        PSEUDOCODE, PSEUDOCODE,         /* LONG, WORD */
        !           171:        PSEUDOCODE, PSEUDONOCODE,       /* BYTE,TEXT */
        !           172:        PSEUDONOCODE, PSEUDONOCODE,     /* DATA, DATA1 */
        !           173:        PSEUDONOCODE, PSEUDONOCODE,     /* DATA2, BSS */
        !           174:        PSEUDONOCODE,                   /* PROC */
        !           175:        PSEUDONOCODE, PSEUDONOCODE,     /* GLOBL, COMM */
        !           176:        PSEUDOCODE, PSEUDOCODE,         /* EVEN, ALIGN */
        !           177:        PSEUDOCODE, PSEUDOCODE,         /* ASCIZ, ASCII */
        !           178:        PSEUDOCODE, PSEUDOCODE,         /* FLOAT, DOUBLE */
        !           179:        PSEUDONOCODE,                   /* STABS */
        !           180:        PSEUDONOCODE, PSEUDONOCODE,     /* STABD, STABN */
        !           181:        PSEUDOCODE, PSEUDONOCODE,       /* SKIP, LCOMM */
        !           182:        PSEUDONOCODE,                   /* CPID */
        !           183:        INSTRTYPE, INSTRTYPE,           /* CSWITCH, FSWITCH */
        !           184:        INSTRTYPE, INSTRTYPE,           /* BRANCH, MOVE */
        !           185:        INSTRTYPE, INSTRTYPE,           /* MOVEM, EXIT */
        !           186:        INSTRTYPE, INSTRTYPE,           /* DBRA, CALL */
        !           187:        INSTRTYPE, INSTRTYPE,           /* JUMP, DJMP */
        !           188:        INSTRTYPE, INSTRTYPE,           /* LINK, CMP */
        !           189:        INSTRTYPE, INSTRTYPE,           /* PEA, ADD */
        !           190:        INSTRTYPE, INSTRTYPE,           /* AND, EXT */
        !           191:        INSTRTYPE, INSTRTYPE,           /* OR, TST */
        !           192:        INSTRTYPE, INSTRTYPE,           /* ASL, ASR */
        !           193:        INSTRTYPE, INSTRTYPE,           /* SUB, UNLK */
        !           194:        INSTRTYPE, INSTRTYPE,           /* LEA, CLR */
        !           195:        INSTRTYPE, INSTRTYPE,           /* BOP, EOR */
        !           196:        INSTRTYPE,                      /* OTHER */
        !           197: };

unix.superglobalmegacorp.com

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