18947Sdlw /* 2*10238Sdlw char id_trapov[] = "@(#)trapov_.c 1.2"; 38947Sdlw * 48947Sdlw * Fortran/C floating-point overflow handler 58947Sdlw * 68947Sdlw * The idea of these routines is to catch floating-point overflows 78947Sdlw * and print an eror message. When we then get a reserved operand 88947Sdlw * exception, we then fix up the value to the highest possible 98947Sdlw * number. Keen, no? 108947Sdlw * Messy, yes! 118947Sdlw * 128947Sdlw * Synopsis: 138947Sdlw * call trapov(n) 148947Sdlw * causes overflows to be trapped, with the first 'n' 158947Sdlw * overflows getting an "Overflow!" message printed. 168947Sdlw * k = ovcnt(0) 178947Sdlw * causes 'k' to get the number of overflows since the 188947Sdlw * last call to trapov(). 198947Sdlw * 208947Sdlw * Gary Klimowicz, April 17, 1981 218947Sdlw * Integerated with libF77: David Wasley, UCB, July 1981. 228947Sdlw */ 238947Sdlw 248947Sdlw # include <stdio.h> 258947Sdlw # include <signal.h> 268947Sdlw # include "opcodes.h" 278947Sdlw # include "../libI77/fiodefs.h" 28*10238Sdlw # define SIG_VAL int (*)() 298947Sdlw 308947Sdlw /* 318947Sdlw * Operand modes 328947Sdlw */ 338947Sdlw # define LITERAL0 0x0 348947Sdlw # define LITERAL1 0x1 358947Sdlw # define LITERAL2 0x2 368947Sdlw # define LITERAL3 0x3 378947Sdlw # define INDEXED 0x4 388947Sdlw # define REGISTER 0x5 398947Sdlw # define REG_DEF 0x6 408947Sdlw # define AUTO_DEC 0x7 418947Sdlw # define AUTO_INC 0x8 428947Sdlw # define AUTO_INC_DEF 0x9 438947Sdlw # define BYTE_DISP 0xa 448947Sdlw # define BYTE_DISP_DEF 0xb 458947Sdlw # define WORD_DISP 0xc 468947Sdlw # define WORD_DISP_DEF 0xd 478947Sdlw # define LONG_DISP 0xe 488947Sdlw # define LONG_DISP_DEF 0xf 498947Sdlw 508947Sdlw /* 518947Sdlw * Operand value types 528947Sdlw */ 538947Sdlw # define F 1 548947Sdlw # define D 2 558947Sdlw # define IDUNNO 3 568947Sdlw 578947Sdlw # define PC 0xf 588947Sdlw # define SP 0xe 598947Sdlw # define FP 0xd 608947Sdlw # define AP 0xc 618947Sdlw 628947Sdlw /* 63*10238Sdlw * trap type codes 64*10238Sdlw */ 65*10238Sdlw # define INT_OVF_T 1 66*10238Sdlw # define INT_DIV_T 2 67*10238Sdlw # define FLT_OVF_T 3 68*10238Sdlw # define FLT_DIV_T 4 69*10238Sdlw # define FLT_UND_T 5 70*10238Sdlw # define DEC_OVF_T 6 71*10238Sdlw # define SUB_RNG_T 7 72*10238Sdlw # define FLT_OVF_F 8 73*10238Sdlw # define FLT_DIV_F 9 74*10238Sdlw # define FLT_UND_F 10 75*10238Sdlw 76*10238Sdlw # define RES_ADR_F 0 77*10238Sdlw # define RES_OPC_F 1 78*10238Sdlw # define RES_OPR_F 2 79*10238Sdlw 80*10238Sdlw /* 818947Sdlw * Potential operand values 828947Sdlw */ 838947Sdlw typedef union operand_types { 848947Sdlw char o_byte; 858947Sdlw short o_word; 868947Sdlw long o_long; 878947Sdlw float o_float; 888947Sdlw long o_quad[2]; 898947Sdlw double o_double; 908947Sdlw } anyval; 918947Sdlw 928947Sdlw /* 938947Sdlw * GLOBAL VARIABLES (we need a few) 948947Sdlw * 958947Sdlw * Actual program counter and locations of registers. 968947Sdlw */ 97*10238Sdlw #if vax 988947Sdlw static char *pc; 998947Sdlw static int *regs0t6; 1008947Sdlw static int *regs7t11; 1018947Sdlw static int max_messages; 1028947Sdlw static int total_overflows; 1038947Sdlw static union { 1048947Sdlw long v_long[2]; 1058947Sdlw double v_double; 1068947Sdlw } retrn; 107*10238Sdlw static int (*sigill_default)() = (SIG_VAL)-1; 108*10238Sdlw static int (*sigfpe_default)(); 109*10238Sdlw #endif vax 1108947Sdlw 1118947Sdlw /* 1128947Sdlw * the fortran unit control table 1138947Sdlw */ 1148947Sdlw extern unit units[]; 1158947Sdlw 116*10238Sdlw /* 117*10238Sdlw * Fortran message table is in main 118*10238Sdlw */ 119*10238Sdlw struct msgtbl { 120*10238Sdlw char *mesg; 121*10238Sdlw int dummy; 122*10238Sdlw }; 123*10238Sdlw extern struct msgtbl act_fpe[]; 124*10238Sdlw 125*10238Sdlw 126*10238Sdlw 1278947Sdlw anyval *get_operand_address(), *addr_of_reg(); 1288947Sdlw char *opcode_name(); 1298947Sdlw 1308947Sdlw /* 1318947Sdlw * This routine sets up the signal handler for the floating-point 1328947Sdlw * and reserved operand interrupts. 1338947Sdlw */ 1348947Sdlw 1358947Sdlw trapov_(count, rtnval) 1368947Sdlw int *count; 1378947Sdlw double *rtnval; 1388947Sdlw { 1398947Sdlw #if vax 1408947Sdlw extern got_overflow(), got_illegal_instruction(); 1418947Sdlw 142*10238Sdlw sigfpe_default = signal(SIGFPE, got_overflow); 143*10238Sdlw if (sigill_default == (SIG_VAL)-1) 144*10238Sdlw sigill_default = signal(SIGILL, got_illegal_instruction); 1458947Sdlw total_overflows = 0; 1468947Sdlw max_messages = *count; 1478947Sdlw retrn.v_double = *rtnval; 1488947Sdlw } 1498947Sdlw 1508947Sdlw 1518947Sdlw 1528947Sdlw /* 1538947Sdlw * got_overflow - routine called when overflow occurs 1548947Sdlw * 1558947Sdlw * This routine just prints a message about the overflow. 1568947Sdlw * It is impossible to find the bad result at this point. 1578947Sdlw * Instead, we wait until we get the reserved operand exception 1588947Sdlw * when we try to use it. This raises the SIGILL signal. 1598947Sdlw */ 1608947Sdlw 1618947Sdlw /*ARGSUSED*/ 1628947Sdlw got_overflow(signo, codeword, myaddr, pc, ps) 1638947Sdlw char *myaddr, *pc; 1648947Sdlw { 165*10238Sdlw int *sp, i; 166*10238Sdlw FILE *ef; 167*10238Sdlw 168*10238Sdlw signal(SIGFPE, got_overflow); 169*10238Sdlw ef = units[STDERR].ufd; 170*10238Sdlw switch (codeword) { 171*10238Sdlw case INT_OVF_T: 172*10238Sdlw case INT_DIV_T: 173*10238Sdlw case FLT_UND_T: 174*10238Sdlw case DEC_OVF_T: 175*10238Sdlw case SUB_RNG_T: 176*10238Sdlw case FLT_OVF_F: 177*10238Sdlw case FLT_DIV_F: 178*10238Sdlw case FLT_UND_F: 179*10238Sdlw if (sigfpe_default > (SIG_VAL)7) 180*10238Sdlw return((*sigfpe_default)(signo, codeword, myaddr, pc, ps)); 181*10238Sdlw else 182*10238Sdlw sigdie(signo, codeword, myaddr, pc, ps); 183*10238Sdlw /* NOTREACHED */ 184*10238Sdlw 185*10238Sdlw case FLT_OVF_T: 186*10238Sdlw case FLT_DIV_T: 187*10238Sdlw if (++total_overflows <= max_messages) { 188*10238Sdlw fprintf(ef, "trapov: %s", 189*10238Sdlw act_fpe[codeword-1].mesg); 190*10238Sdlw if (total_overflows == max_messages) 191*10238Sdlw fprintf(ef, ": No more messages will be printed.\n"); 192*10238Sdlw else 193*10238Sdlw fputc('\n', ef); 194*10238Sdlw } 195*10238Sdlw return; 1968947Sdlw } 1978947Sdlw #endif vax 1988947Sdlw } 1998947Sdlw 2008947Sdlw int 2018947Sdlw ovcnt_() 2028947Sdlw { 2038947Sdlw return total_overflows; 2048947Sdlw } 2058947Sdlw 2068947Sdlw #if vax 2078947Sdlw /* 2088947Sdlw * got_illegal_instruction - handle "illegal instruction" signals. 2098947Sdlw * 2108947Sdlw * This really deals only with reserved operand exceptions. 2118947Sdlw * Since there is no way to check this directly, we look at the 2128947Sdlw * opcode of the instruction we are executing to see if it is a 2138947Sdlw * floating-point operation (with floating-point operands, not 2148947Sdlw * just results). 2158947Sdlw * 2168947Sdlw * This is complicated by the fact that the registers that will 2178947Sdlw * eventually be restored are saved in two places. registers 7-11 2188947Sdlw * are saved by this routine, and are in its call frame. (we have 2198947Sdlw * to take special care that these registers are specified in 2208947Sdlw * the procedure entry mask here.) 2218947Sdlw * Registers 0-6 are saved at interrupt time, and are at a offset 2228947Sdlw * -8 from the 'signo' parameter below. 2238947Sdlw * There is ane extremely inimate connection between the value of 2248947Sdlw * the entry mask set by the 'makefile' script, and the constants 2258947Sdlw * used in the register offset calculations below. 2268947Sdlw * Can someone think of a better way to do this? 2278947Sdlw */ 2288947Sdlw 2298947Sdlw /*ARGSUSED*/ 2308947Sdlw got_illegal_instruction(signo, codeword, myaddr, trap_pc, ps) 2318947Sdlw char *myaddr, *trap_pc; 2328947Sdlw { 2338947Sdlw int first_local[1]; /* must be first */ 2348947Sdlw int i, opcode, type, o_no, no_reserved; 2358947Sdlw anyval *opnd; 2368947Sdlw 2378947Sdlw regs7t11 = &first_local[0]; 2388947Sdlw regs0t6 = &signo - 8; 2398947Sdlw pc = trap_pc; 2408947Sdlw 2418947Sdlw opcode = fetch_byte() & 0xff; 2428947Sdlw no_reserved = 0; 243*10238Sdlw if (codeword != RES_OPR_F || !is_floating_operation(opcode)) { 244*10238Sdlw if (sigill_default > (SIG_VAL)7) 245*10238Sdlw return((*sigill_default)(signo, codeword, myaddr, trap_pc, ps)); 246*10238Sdlw else 247*10238Sdlw sigdie(signo, codeword, myaddr, trap_pc, ps); 248*10238Sdlw /* NOTREACHED */ 2498947Sdlw } 2508947Sdlw 2518947Sdlw if (opcode == POLYD || opcode == POLYF) { 2528947Sdlw got_illegal_poly(opcode); 2538947Sdlw return; 2548947Sdlw } 2558947Sdlw 2568947Sdlw if (opcode == EMODD || opcode == EMODF) { 2578947Sdlw got_illegal_emod(opcode); 2588947Sdlw return; 2598947Sdlw } 2608947Sdlw 2618947Sdlw /* 2628947Sdlw * This opcode wasn't "unusual". 2638947Sdlw * Look at the operands to try and find a reserved operand. 2648947Sdlw */ 2658947Sdlw for (o_no = 1; o_no <= no_operands(opcode); ++o_no) { 2668947Sdlw type = operand_type(opcode, o_no); 2678947Sdlw if (type != F && type != D) { 2688947Sdlw advance_pc(type); 2698947Sdlw continue; 2708947Sdlw } 2718947Sdlw 2728947Sdlw /* F or D operand. Check it out */ 2738947Sdlw opnd = get_operand_address(type); 2748947Sdlw if (opnd == NULL) { 2758947Sdlw fprintf(units[STDERR].ufd, "Can't get operand address: 0x%x, %d\n", 2768947Sdlw pc, o_no); 2778947Sdlw force_abort(); 2788947Sdlw } 2798947Sdlw if (type == F && opnd->o_long == 0x00008000) { 2808947Sdlw /* found one */ 2818947Sdlw opnd->o_long = retrn.v_long[0]; 2828947Sdlw ++no_reserved; 2838947Sdlw } else if (type == D && opnd->o_long == 0x00008000) { 2848947Sdlw /* found one here, too! */ 2858947Sdlw opnd->o_quad[0] = retrn.v_long[0]; 2868947Sdlw /* Fix next pointer */ 2878947Sdlw if (opnd == addr_of_reg(6)) opnd = addr_of_reg(7); 2888947Sdlw else opnd = (anyval *) ((char *) opnd + 4); 2898947Sdlw opnd->o_quad[0] = retrn.v_long[1]; 2908947Sdlw ++no_reserved; 2918947Sdlw } 2928947Sdlw 2938947Sdlw } 2948947Sdlw 2958947Sdlw if (no_reserved == 0) { 2968947Sdlw fprintf(units[STDERR].ufd, "Can't find any reserved operand!\n"); 2978947Sdlw force_abort(); 2988947Sdlw } 2998947Sdlw } 3008947Sdlw /* 3018947Sdlw * is_floating_exception - was the operation code for a floating instruction? 3028947Sdlw */ 3038947Sdlw 3048947Sdlw is_floating_operation(opcode) 3058947Sdlw int opcode; 3068947Sdlw { 3078947Sdlw switch (opcode) { 3088947Sdlw case ACBD: case ACBF: case ADDD2: case ADDD3: 3098947Sdlw case ADDF2: case ADDF3: case CMPD: case CMPF: 3108947Sdlw case CVTDB: case CVTDF: case CVTDL: case CVTDW: 3118947Sdlw case CVTFB: case CVTFD: case CVTFL: case CVTFW: 3128947Sdlw case CVTRDL: case CVTRFL: case DIVD2: case DIVD3: 3138947Sdlw case DIVF2: case DIVF3: case EMODD: case EMODF: 3148947Sdlw case MNEGD: case MNEGF: case MOVD: case MOVF: 3158947Sdlw case MULD2: case MULD3: case MULF2: case MULF3: 3168947Sdlw case POLYD: case POLYF: case SUBD2: case SUBD3: 3178947Sdlw case SUBF2: case SUBF3: case TSTD: case TSTF: 3188947Sdlw return 1; 3198947Sdlw 3208947Sdlw default: 3218947Sdlw return 0; 3228947Sdlw } 3238947Sdlw } 3248947Sdlw /* 3258947Sdlw * got_illegal_poly - handle an illegal POLY[DF] instruction. 3268947Sdlw * 3278947Sdlw * We don't do anything here yet. 3288947Sdlw */ 3298947Sdlw 3308947Sdlw /*ARGSUSED*/ 3318947Sdlw got_illegal_poly(opcode) 3328947Sdlw { 3338947Sdlw fprintf(units[STDERR].ufd, "Can't do 'poly' instructions yet\n"); 3348947Sdlw force_abort(); 3358947Sdlw } 3368947Sdlw 3378947Sdlw 3388947Sdlw 3398947Sdlw /* 3408947Sdlw * got_illegal_emod - handle illegal EMOD[DF] instruction. 3418947Sdlw * 3428947Sdlw * We don't do anything here yet. 3438947Sdlw */ 3448947Sdlw 3458947Sdlw /*ARGSUSED*/ 3468947Sdlw got_illegal_emod(opcode) 3478947Sdlw { 3488947Sdlw fprintf(units[STDERR].ufd, "Can't do 'emod' instructions yet\n"); 3498947Sdlw force_abort(); 3508947Sdlw } 3518947Sdlw 3528947Sdlw 3538947Sdlw /* 3548947Sdlw * no_operands - determine the number of operands in this instruction. 3558947Sdlw * 3568947Sdlw */ 3578947Sdlw 3588947Sdlw no_operands(opcode) 3598947Sdlw { 3608947Sdlw switch (opcode) { 3618947Sdlw case ACBD: 3628947Sdlw case ACBF: 3638947Sdlw return 3; 3648947Sdlw 3658947Sdlw case MNEGD: 3668947Sdlw case MNEGF: 3678947Sdlw case MOVD: 3688947Sdlw case MOVF: 3698947Sdlw case TSTD: 3708947Sdlw case TSTF: 3718947Sdlw return 1; 3728947Sdlw 3738947Sdlw default: 3748947Sdlw return 2; 3758947Sdlw } 3768947Sdlw } 3778947Sdlw 3788947Sdlw 3798947Sdlw 3808947Sdlw /* 3818947Sdlw * operand_type - is the operand a D or an F? 3828947Sdlw * 3838947Sdlw * We are only descriminating between Floats and Doubles here. 3848947Sdlw * Other operands may be possible on exotic instructions. 3858947Sdlw */ 3868947Sdlw 3878947Sdlw /*ARGSUSED*/ 3888947Sdlw operand_type(opcode, no) 3898947Sdlw { 3908947Sdlw if (opcode >= 0x40 && opcode <= 0x56) return F; 3918947Sdlw if (opcode >= 0x60 && opcode <= 0x76) return D; 3928947Sdlw return IDUNNO; 3938947Sdlw } 3948947Sdlw 3958947Sdlw 3968947Sdlw 3978947Sdlw /* 3988947Sdlw * advance_pc - Advance the program counter past an operand. 3998947Sdlw * 4008947Sdlw * We just bump the pc by the appropriate values. 4018947Sdlw */ 4028947Sdlw 4038947Sdlw advance_pc(type) 4048947Sdlw { 4058947Sdlw register int mode, reg; 4068947Sdlw 4078947Sdlw mode = fetch_byte(); 4088947Sdlw reg = mode & 0xf; 4098947Sdlw mode = (mode >> 4) & 0xf; 4108947Sdlw switch (mode) { 4118947Sdlw case LITERAL0: 4128947Sdlw case LITERAL1: 4138947Sdlw case LITERAL2: 4148947Sdlw case LITERAL3: 4158947Sdlw return; 4168947Sdlw 4178947Sdlw case INDEXED: 4188947Sdlw advance_pc(type); 4198947Sdlw return; 4208947Sdlw 4218947Sdlw case REGISTER: 4228947Sdlw case REG_DEF: 4238947Sdlw case AUTO_DEC: 4248947Sdlw return; 4258947Sdlw 4268947Sdlw case AUTO_INC: 4278947Sdlw if (reg == PC) { 4288947Sdlw if (type == F) (void) fetch_long(); 4298947Sdlw else if (type == D) { 4308947Sdlw (void) fetch_long(); 4318947Sdlw (void) fetch_long(); 4328947Sdlw } else { 4338947Sdlw fprintf(units[STDERR].ufd, "Bad type %d in advance\n", 4348947Sdlw type); 4358947Sdlw force_abort(); 4368947Sdlw } 4378947Sdlw } 4388947Sdlw return; 4398947Sdlw 4408947Sdlw case AUTO_INC_DEF: 4418947Sdlw if (reg == PC) (void) fetch_long(); 4428947Sdlw return; 4438947Sdlw 4448947Sdlw case BYTE_DISP: 4458947Sdlw case BYTE_DISP_DEF: 4468947Sdlw (void) fetch_byte(); 4478947Sdlw return; 4488947Sdlw 4498947Sdlw case WORD_DISP: 4508947Sdlw case WORD_DISP_DEF: 4518947Sdlw (void) fetch_word(); 4528947Sdlw return; 4538947Sdlw 4548947Sdlw case LONG_DISP: 4558947Sdlw case LONG_DISP_DEF: 4568947Sdlw (void) fetch_long(); 4578947Sdlw return; 4588947Sdlw 4598947Sdlw default: 4608947Sdlw fprintf(units[STDERR].ufd, "Bad mode 0x%x in op_length()\n", mode); 4618947Sdlw force_abort(); 4628947Sdlw } 4638947Sdlw } 4648947Sdlw 4658947Sdlw 4668947Sdlw anyval * 4678947Sdlw get_operand_address(type) 4688947Sdlw { 4698947Sdlw register int mode, reg, base; 4708947Sdlw 4718947Sdlw mode = fetch_byte() & 0xff; 4728947Sdlw reg = mode & 0xf; 4738947Sdlw mode = (mode >> 4) & 0xf; 4748947Sdlw switch (mode) { 4758947Sdlw case LITERAL0: 4768947Sdlw case LITERAL1: 4778947Sdlw case LITERAL2: 4788947Sdlw case LITERAL3: 4798947Sdlw return NULL; 4808947Sdlw 4818947Sdlw case INDEXED: 4828947Sdlw base = (int) get_operand_address(type); 4838947Sdlw if (base == NULL) return NULL; 4848947Sdlw base += contents_of_reg(reg)*type_length(type); 4858947Sdlw return (anyval *) base; 4868947Sdlw 4878947Sdlw case REGISTER: 4888947Sdlw return addr_of_reg(reg); 4898947Sdlw 4908947Sdlw case REG_DEF: 4918947Sdlw return (anyval *) contents_of_reg(reg); 4928947Sdlw 4938947Sdlw case AUTO_DEC: 4948947Sdlw return (anyval *) (contents_of_reg(reg) 4958947Sdlw - type_length(type)); 4968947Sdlw 4978947Sdlw case AUTO_INC: 4988947Sdlw return (anyval *) contents_of_reg(reg); 4998947Sdlw 5008947Sdlw case AUTO_INC_DEF: 5018947Sdlw return (anyval *) * (long *) contents_of_reg(reg); 5028947Sdlw 5038947Sdlw case BYTE_DISP: 5048947Sdlw base = fetch_byte(); 5058947Sdlw base += contents_of_reg(reg); 5068947Sdlw return (anyval *) base; 5078947Sdlw 5088947Sdlw case BYTE_DISP_DEF: 5098947Sdlw base = fetch_byte(); 5108947Sdlw base += contents_of_reg(reg); 5118947Sdlw return (anyval *) * (long *) base; 5128947Sdlw 5138947Sdlw case WORD_DISP: 5148947Sdlw base = fetch_word(); 5158947Sdlw base += contents_of_reg(reg); 5168947Sdlw return (anyval *) base; 5178947Sdlw 5188947Sdlw case WORD_DISP_DEF: 5198947Sdlw base = fetch_word(); 5208947Sdlw base += contents_of_reg(reg); 5218947Sdlw return (anyval *) * (long *) base; 5228947Sdlw 5238947Sdlw case LONG_DISP: 5248947Sdlw base = fetch_long(); 5258947Sdlw base += contents_of_reg(reg); 5268947Sdlw return (anyval *) base; 5278947Sdlw 5288947Sdlw case LONG_DISP_DEF: 5298947Sdlw base = fetch_long(); 5308947Sdlw base += contents_of_reg(reg); 5318947Sdlw return (anyval *) * (long *) base; 5328947Sdlw 5338947Sdlw default: 5348947Sdlw fprintf(units[STDERR].ufd, "Bad mode 0x%x in get_addr()\n", mode); 5358947Sdlw force_abort(); 5368947Sdlw } 5378947Sdlw return NULL; 5388947Sdlw } 5398947Sdlw 5408947Sdlw 5418947Sdlw 5428947Sdlw contents_of_reg(reg) 5438947Sdlw { 5448947Sdlw int value; 5458947Sdlw 5468947Sdlw if (reg == PC) value = (int) pc; 5478947Sdlw else if (reg == SP) value = (int) ®s0t6[6]; 5488947Sdlw else if (reg == FP) value = regs0t6[-2]; 5498947Sdlw else if (reg == AP) value = regs0t6[-3]; 5508947Sdlw else if (reg >= 0 && reg <= 6) value = regs0t6[reg]; 5518947Sdlw else if (reg >= 7 && reg <= 11) value = regs7t11[reg]; 5528947Sdlw else { 5538947Sdlw fprintf(units[STDERR].ufd, "Bad register 0x%x to contents_of()\n", reg); 5548947Sdlw force_abort(); 5558947Sdlw value = -1; 5568947Sdlw } 5578947Sdlw return value; 5588947Sdlw } 5598947Sdlw 5608947Sdlw 5618947Sdlw anyval * 5628947Sdlw addr_of_reg(reg) 5638947Sdlw { 5648947Sdlw if (reg >= 0 && reg <= 6) { 5658947Sdlw return (anyval *) ®s0t6[reg]; 5668947Sdlw } 5678947Sdlw if (reg >= 7 && reg <= 11) { 5688947Sdlw return (anyval *) ®s7t11[reg]; 5698947Sdlw } 5708947Sdlw fprintf(units[STDERR].ufd, "Bad reg 0x%x to addr_of()\n", reg); 5718947Sdlw force_abort(); 5728947Sdlw return NULL; 5738947Sdlw } 5748947Sdlw /* 5758947Sdlw * fetch_{byte, word, long} - extract values from the PROGRAM area. 5768947Sdlw * 5778947Sdlw * These routines are used in the operand decoding to extract various 5788947Sdlw * fields from where the program counter points. This is because the 5798947Sdlw * addressing on the Vax is dynamic: the program counter advances 5808947Sdlw * while we are grabbing operands, as well as when we pass instructions. 5818947Sdlw * This makes things a bit messy, but I can't help it. 5828947Sdlw */ 5838947Sdlw fetch_byte() 5848947Sdlw { 5858947Sdlw return *pc++; 5868947Sdlw } 5878947Sdlw 5888947Sdlw 5898947Sdlw 5908947Sdlw fetch_word() 5918947Sdlw { 5928947Sdlw int *old_pc; 5938947Sdlw 5948947Sdlw old_pc = (int *) pc; 5958947Sdlw pc += 2; 5968947Sdlw return *old_pc; 5978947Sdlw } 5988947Sdlw 5998947Sdlw 6008947Sdlw 6018947Sdlw fetch_long() 6028947Sdlw { 6038947Sdlw long *old_pc; 6048947Sdlw 6058947Sdlw old_pc = (long *) pc; 6068947Sdlw pc += 4; 6078947Sdlw return *old_pc; 6088947Sdlw } 6098947Sdlw /* 6108947Sdlw * force_abort - force us to abort. 6118947Sdlw * 6128947Sdlw * We have to change the signal handler for illegal instructions back, 6138947Sdlw * or we'll end up calling 'got_illegal_instruction()' again when 6148947Sdlw * abort() does it's dirty work. 6158947Sdlw */ 6168947Sdlw force_abort() 6178947Sdlw { 618*10238Sdlw signal(SIGILL, SIG_DFL); 6198947Sdlw abort(); 6208947Sdlw } 6218947Sdlw 6228947Sdlw 6238947Sdlw type_length(type) 6248947Sdlw { 6258947Sdlw if (type == F) return 4; 6268947Sdlw if (type == D) return 8; 6278947Sdlw fprintf(units[STDERR].ufd, "Bad type 0x%x in type_length()\n", type); 6288947Sdlw force_abort(); 6298947Sdlw return -1; 6308947Sdlw } 6318947Sdlw 6328947Sdlw 6338947Sdlw 6348947Sdlw char *opcode_name(opcode) 6358947Sdlw { 6368947Sdlw switch (opcode) { 6378947Sdlw case ACBD: return "ACBD"; 6388947Sdlw case ACBF: return "ACBF"; 6398947Sdlw case ADDD2: return "ADDD2"; 6408947Sdlw case ADDD3: return "ADDD3"; 6418947Sdlw case ADDF2: return "ADDF2"; 6428947Sdlw case ADDF3: return "ADDF3"; 6438947Sdlw case CMPD: return "CMPD"; 6448947Sdlw case CMPF: return "CMPF"; 6458947Sdlw case CVTDB: return "CVTDB"; 6468947Sdlw case CVTDF: return "CVTDF"; 6478947Sdlw case CVTDL: return "CVTDL"; 6488947Sdlw case CVTDW: return "CVTDW"; 6498947Sdlw case CVTFB: return "CVTFB"; 6508947Sdlw case CVTFD: return "CVTFD"; 6518947Sdlw case CVTFL: return "CVTFL"; 6528947Sdlw case CVTFW: return "CVTFW"; 6538947Sdlw case CVTRDL: return "CVTRDL"; 6548947Sdlw case CVTRFL: return "CVTRFL"; 6558947Sdlw case DIVD2: return "DIVD2"; 6568947Sdlw case DIVD3: return "DIVD3"; 6578947Sdlw case DIVF2: return "DIVF2"; 6588947Sdlw case DIVF3: return "DIVF3"; 6598947Sdlw case EMODD: return "EMODD"; 6608947Sdlw case EMODF: return "EMODF"; 6618947Sdlw case MNEGD: return "MNEGD"; 6628947Sdlw case MNEGF: return "MNEGF"; 6638947Sdlw case MOVD: return "MOVD"; 6648947Sdlw case MOVF: return "MOVF"; 6658947Sdlw case MULD2: return "MULD2"; 6668947Sdlw case MULD3: return "MULD3"; 6678947Sdlw case MULF2: return "MULF2"; 6688947Sdlw case MULF3: return "MULF3"; 6698947Sdlw case POLYD: return "POLYD"; 6708947Sdlw case POLYF: return "POLYF"; 6718947Sdlw case SUBD2: return "SUBD2"; 6728947Sdlw case SUBD3: return "SUBD3"; 6738947Sdlw case SUBF2: return "SUBF2"; 6748947Sdlw case SUBF3: return "SUBF3"; 6758947Sdlw case TSTD: return "TSTD"; 6768947Sdlw case TSTF: return "TSTF"; 6778947Sdlw } 6788947Sdlw } 6798947Sdlw #endif vax 680