|
|
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: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.