18947Sdlw /* 2*20186Slibs char id_trapov[] = "@(#)trapov_.c 1.3"; 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" 2810238Sdlw # 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 /* 6310238Sdlw * trap type codes 6410238Sdlw */ 6510238Sdlw # define INT_OVF_T 1 6610238Sdlw # define INT_DIV_T 2 6710238Sdlw # define FLT_OVF_T 3 6810238Sdlw # define FLT_DIV_T 4 6910238Sdlw # define FLT_UND_T 5 7010238Sdlw # define DEC_OVF_T 6 7110238Sdlw # define SUB_RNG_T 7 7210238Sdlw # define FLT_OVF_F 8 7310238Sdlw # define FLT_DIV_F 9 7410238Sdlw # define FLT_UND_F 10 7510238Sdlw 7610238Sdlw # define RES_ADR_F 0 7710238Sdlw # define RES_OPC_F 1 7810238Sdlw # define RES_OPR_F 2 7910238Sdlw 8010238Sdlw /* 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 */ 9710238Sdlw #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; 10710238Sdlw static int (*sigill_default)() = (SIG_VAL)-1; 10810238Sdlw static int (*sigfpe_default)(); 10910238Sdlw #endif vax 1108947Sdlw 1118947Sdlw /* 1128947Sdlw * the fortran unit control table 1138947Sdlw */ 1148947Sdlw extern unit units[]; 1158947Sdlw 11610238Sdlw /* 11710238Sdlw * Fortran message table is in main 11810238Sdlw */ 11910238Sdlw struct msgtbl { 12010238Sdlw char *mesg; 12110238Sdlw int dummy; 12210238Sdlw }; 12310238Sdlw extern struct msgtbl act_fpe[]; 12410238Sdlw 12510238Sdlw 12610238Sdlw 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 14210238Sdlw sigfpe_default = signal(SIGFPE, got_overflow); 14310238Sdlw if (sigill_default == (SIG_VAL)-1) 14410238Sdlw 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 { 16510238Sdlw int *sp, i; 16610238Sdlw FILE *ef; 16710238Sdlw 16810238Sdlw signal(SIGFPE, got_overflow); 16910238Sdlw ef = units[STDERR].ufd; 17010238Sdlw switch (codeword) { 17110238Sdlw case INT_OVF_T: 17210238Sdlw case INT_DIV_T: 17310238Sdlw case FLT_UND_T: 17410238Sdlw case DEC_OVF_T: 17510238Sdlw case SUB_RNG_T: 17610238Sdlw case FLT_OVF_F: 17710238Sdlw case FLT_DIV_F: 17810238Sdlw case FLT_UND_F: 17910238Sdlw if (sigfpe_default > (SIG_VAL)7) 18010238Sdlw return((*sigfpe_default)(signo, codeword, myaddr, pc, ps)); 18110238Sdlw else 18210238Sdlw sigdie(signo, codeword, myaddr, pc, ps); 18310238Sdlw /* NOTREACHED */ 18410238Sdlw 18510238Sdlw case FLT_OVF_T: 18610238Sdlw case FLT_DIV_T: 18710238Sdlw if (++total_overflows <= max_messages) { 18810238Sdlw fprintf(ef, "trapov: %s", 18910238Sdlw act_fpe[codeword-1].mesg); 19010238Sdlw if (total_overflows == max_messages) 19110238Sdlw fprintf(ef, ": No more messages will be printed.\n"); 19210238Sdlw else 19310238Sdlw fputc('\n', ef); 19410238Sdlw } 19510238Sdlw 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; 24310238Sdlw if (codeword != RES_OPR_F || !is_floating_operation(opcode)) { 24410238Sdlw if (sigill_default > (SIG_VAL)7) 24510238Sdlw return((*sigill_default)(signo, codeword, myaddr, trap_pc, ps)); 24610238Sdlw else 24710238Sdlw sigdie(signo, codeword, myaddr, trap_pc, ps); 24810238Sdlw /* 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); 277*20186Slibs f77_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"); 297*20186Slibs f77_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"); 334*20186Slibs f77_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"); 349*20186Slibs f77_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); 435*20186Slibs f77_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); 461*20186Slibs f77_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); 535*20186Slibs f77_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); 554*20186Slibs f77_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); 571*20186Slibs f77_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 } 609*20186Slibs 6108947Sdlw 6118947Sdlw type_length(type) 6128947Sdlw { 6138947Sdlw if (type == F) return 4; 6148947Sdlw if (type == D) return 8; 6158947Sdlw fprintf(units[STDERR].ufd, "Bad type 0x%x in type_length()\n", type); 616*20186Slibs f77_abort(); 6178947Sdlw return -1; 6188947Sdlw } 6198947Sdlw 6208947Sdlw 6218947Sdlw 6228947Sdlw char *opcode_name(opcode) 6238947Sdlw { 6248947Sdlw switch (opcode) { 6258947Sdlw case ACBD: return "ACBD"; 6268947Sdlw case ACBF: return "ACBF"; 6278947Sdlw case ADDD2: return "ADDD2"; 6288947Sdlw case ADDD3: return "ADDD3"; 6298947Sdlw case ADDF2: return "ADDF2"; 6308947Sdlw case ADDF3: return "ADDF3"; 6318947Sdlw case CMPD: return "CMPD"; 6328947Sdlw case CMPF: return "CMPF"; 6338947Sdlw case CVTDB: return "CVTDB"; 6348947Sdlw case CVTDF: return "CVTDF"; 6358947Sdlw case CVTDL: return "CVTDL"; 6368947Sdlw case CVTDW: return "CVTDW"; 6378947Sdlw case CVTFB: return "CVTFB"; 6388947Sdlw case CVTFD: return "CVTFD"; 6398947Sdlw case CVTFL: return "CVTFL"; 6408947Sdlw case CVTFW: return "CVTFW"; 6418947Sdlw case CVTRDL: return "CVTRDL"; 6428947Sdlw case CVTRFL: return "CVTRFL"; 6438947Sdlw case DIVD2: return "DIVD2"; 6448947Sdlw case DIVD3: return "DIVD3"; 6458947Sdlw case DIVF2: return "DIVF2"; 6468947Sdlw case DIVF3: return "DIVF3"; 6478947Sdlw case EMODD: return "EMODD"; 6488947Sdlw case EMODF: return "EMODF"; 6498947Sdlw case MNEGD: return "MNEGD"; 6508947Sdlw case MNEGF: return "MNEGF"; 6518947Sdlw case MOVD: return "MOVD"; 6528947Sdlw case MOVF: return "MOVF"; 6538947Sdlw case MULD2: return "MULD2"; 6548947Sdlw case MULD3: return "MULD3"; 6558947Sdlw case MULF2: return "MULF2"; 6568947Sdlw case MULF3: return "MULF3"; 6578947Sdlw case POLYD: return "POLYD"; 6588947Sdlw case POLYF: return "POLYF"; 6598947Sdlw case SUBD2: return "SUBD2"; 6608947Sdlw case SUBD3: return "SUBD3"; 6618947Sdlw case SUBF2: return "SUBF2"; 6628947Sdlw case SUBF3: return "SUBF3"; 6638947Sdlw case TSTD: return "TSTD"; 6648947Sdlw case TSTF: return "TSTF"; 6658947Sdlw } 6668947Sdlw } 6678947Sdlw #endif vax 668