18947Sdlw /* 222990Skre * Copyright (c) 1980 Regents of the University of California. 322990Skre * All rights reserved. The Berkeley software License Agreement 422990Skre * specifies the terms and conditions for redistribution. 58947Sdlw * 6*22995Skre * @(#)trapov_.c 5.2 06/07/85 7*22995Skre * 88947Sdlw * Fortran/C floating-point overflow handler 98947Sdlw * 108947Sdlw * The idea of these routines is to catch floating-point overflows 118947Sdlw * and print an eror message. When we then get a reserved operand 128947Sdlw * exception, we then fix up the value to the highest possible 138947Sdlw * number. Keen, no? 148947Sdlw * Messy, yes! 158947Sdlw * 168947Sdlw * Synopsis: 178947Sdlw * call trapov(n) 188947Sdlw * causes overflows to be trapped, with the first 'n' 198947Sdlw * overflows getting an "Overflow!" message printed. 208947Sdlw * k = ovcnt(0) 218947Sdlw * causes 'k' to get the number of overflows since the 228947Sdlw * last call to trapov(). 238947Sdlw * 248947Sdlw * Gary Klimowicz, April 17, 1981 258947Sdlw * Integerated with libF77: David Wasley, UCB, July 1981. 268947Sdlw */ 278947Sdlw 288947Sdlw # include <stdio.h> 298947Sdlw # include <signal.h> 308947Sdlw # include "opcodes.h" 318947Sdlw # include "../libI77/fiodefs.h" 3210238Sdlw # define SIG_VAL int (*)() 338947Sdlw 348947Sdlw /* 358947Sdlw * Operand modes 368947Sdlw */ 378947Sdlw # define LITERAL0 0x0 388947Sdlw # define LITERAL1 0x1 398947Sdlw # define LITERAL2 0x2 408947Sdlw # define LITERAL3 0x3 418947Sdlw # define INDEXED 0x4 428947Sdlw # define REGISTER 0x5 438947Sdlw # define REG_DEF 0x6 448947Sdlw # define AUTO_DEC 0x7 458947Sdlw # define AUTO_INC 0x8 468947Sdlw # define AUTO_INC_DEF 0x9 478947Sdlw # define BYTE_DISP 0xa 488947Sdlw # define BYTE_DISP_DEF 0xb 498947Sdlw # define WORD_DISP 0xc 508947Sdlw # define WORD_DISP_DEF 0xd 518947Sdlw # define LONG_DISP 0xe 528947Sdlw # define LONG_DISP_DEF 0xf 538947Sdlw 548947Sdlw /* 558947Sdlw * Operand value types 568947Sdlw */ 578947Sdlw # define F 1 588947Sdlw # define D 2 598947Sdlw # define IDUNNO 3 608947Sdlw 618947Sdlw # define PC 0xf 628947Sdlw # define SP 0xe 638947Sdlw # define FP 0xd 648947Sdlw # define AP 0xc 658947Sdlw 668947Sdlw /* 6710238Sdlw * trap type codes 6810238Sdlw */ 6910238Sdlw # define INT_OVF_T 1 7010238Sdlw # define INT_DIV_T 2 7110238Sdlw # define FLT_OVF_T 3 7210238Sdlw # define FLT_DIV_T 4 7310238Sdlw # define FLT_UND_T 5 7410238Sdlw # define DEC_OVF_T 6 7510238Sdlw # define SUB_RNG_T 7 7610238Sdlw # define FLT_OVF_F 8 7710238Sdlw # define FLT_DIV_F 9 7810238Sdlw # define FLT_UND_F 10 7910238Sdlw 8010238Sdlw # define RES_ADR_F 0 8110238Sdlw # define RES_OPC_F 1 8210238Sdlw # define RES_OPR_F 2 8310238Sdlw 8410238Sdlw /* 858947Sdlw * Potential operand values 868947Sdlw */ 878947Sdlw typedef union operand_types { 888947Sdlw char o_byte; 898947Sdlw short o_word; 908947Sdlw long o_long; 918947Sdlw float o_float; 928947Sdlw long o_quad[2]; 938947Sdlw double o_double; 948947Sdlw } anyval; 958947Sdlw 968947Sdlw /* 978947Sdlw * GLOBAL VARIABLES (we need a few) 988947Sdlw * 998947Sdlw * Actual program counter and locations of registers. 1008947Sdlw */ 10110238Sdlw #if vax 1028947Sdlw static char *pc; 1038947Sdlw static int *regs0t6; 1048947Sdlw static int *regs7t11; 1058947Sdlw static int max_messages; 1068947Sdlw static int total_overflows; 1078947Sdlw static union { 1088947Sdlw long v_long[2]; 1098947Sdlw double v_double; 1108947Sdlw } retrn; 11110238Sdlw static int (*sigill_default)() = (SIG_VAL)-1; 11210238Sdlw static int (*sigfpe_default)(); 11310238Sdlw #endif vax 1148947Sdlw 1158947Sdlw /* 1168947Sdlw * the fortran unit control table 1178947Sdlw */ 1188947Sdlw extern unit units[]; 1198947Sdlw 12010238Sdlw /* 12110238Sdlw * Fortran message table is in main 12210238Sdlw */ 12310238Sdlw struct msgtbl { 12410238Sdlw char *mesg; 12510238Sdlw int dummy; 12610238Sdlw }; 12710238Sdlw extern struct msgtbl act_fpe[]; 12810238Sdlw 12910238Sdlw 13010238Sdlw 1318947Sdlw anyval *get_operand_address(), *addr_of_reg(); 1328947Sdlw char *opcode_name(); 1338947Sdlw 1348947Sdlw /* 1358947Sdlw * This routine sets up the signal handler for the floating-point 1368947Sdlw * and reserved operand interrupts. 1378947Sdlw */ 1388947Sdlw 1398947Sdlw trapov_(count, rtnval) 1408947Sdlw int *count; 1418947Sdlw double *rtnval; 1428947Sdlw { 1438947Sdlw #if vax 1448947Sdlw extern got_overflow(), got_illegal_instruction(); 1458947Sdlw 14610238Sdlw sigfpe_default = signal(SIGFPE, got_overflow); 14710238Sdlw if (sigill_default == (SIG_VAL)-1) 14810238Sdlw sigill_default = signal(SIGILL, got_illegal_instruction); 1498947Sdlw total_overflows = 0; 1508947Sdlw max_messages = *count; 1518947Sdlw retrn.v_double = *rtnval; 1528947Sdlw } 1538947Sdlw 1548947Sdlw 1558947Sdlw 1568947Sdlw /* 1578947Sdlw * got_overflow - routine called when overflow occurs 1588947Sdlw * 1598947Sdlw * This routine just prints a message about the overflow. 1608947Sdlw * It is impossible to find the bad result at this point. 1618947Sdlw * Instead, we wait until we get the reserved operand exception 1628947Sdlw * when we try to use it. This raises the SIGILL signal. 1638947Sdlw */ 1648947Sdlw 1658947Sdlw /*ARGSUSED*/ 1668947Sdlw got_overflow(signo, codeword, myaddr, pc, ps) 1678947Sdlw char *myaddr, *pc; 1688947Sdlw { 16910238Sdlw int *sp, i; 17010238Sdlw FILE *ef; 17110238Sdlw 17210238Sdlw signal(SIGFPE, got_overflow); 17310238Sdlw ef = units[STDERR].ufd; 17410238Sdlw switch (codeword) { 17510238Sdlw case INT_OVF_T: 17610238Sdlw case INT_DIV_T: 17710238Sdlw case FLT_UND_T: 17810238Sdlw case DEC_OVF_T: 17910238Sdlw case SUB_RNG_T: 18010238Sdlw case FLT_OVF_F: 18110238Sdlw case FLT_DIV_F: 18210238Sdlw case FLT_UND_F: 18310238Sdlw if (sigfpe_default > (SIG_VAL)7) 18410238Sdlw return((*sigfpe_default)(signo, codeword, myaddr, pc, ps)); 18510238Sdlw else 18610238Sdlw sigdie(signo, codeword, myaddr, pc, ps); 18710238Sdlw /* NOTREACHED */ 18810238Sdlw 18910238Sdlw case FLT_OVF_T: 19010238Sdlw case FLT_DIV_T: 19110238Sdlw if (++total_overflows <= max_messages) { 19210238Sdlw fprintf(ef, "trapov: %s", 19310238Sdlw act_fpe[codeword-1].mesg); 19410238Sdlw if (total_overflows == max_messages) 19510238Sdlw fprintf(ef, ": No more messages will be printed.\n"); 19610238Sdlw else 19710238Sdlw fputc('\n', ef); 19810238Sdlw } 19910238Sdlw return; 2008947Sdlw } 2018947Sdlw #endif vax 2028947Sdlw } 2038947Sdlw 2048947Sdlw int 2058947Sdlw ovcnt_() 2068947Sdlw { 2078947Sdlw return total_overflows; 2088947Sdlw } 2098947Sdlw 2108947Sdlw #if vax 2118947Sdlw /* 2128947Sdlw * got_illegal_instruction - handle "illegal instruction" signals. 2138947Sdlw * 2148947Sdlw * This really deals only with reserved operand exceptions. 2158947Sdlw * Since there is no way to check this directly, we look at the 2168947Sdlw * opcode of the instruction we are executing to see if it is a 2178947Sdlw * floating-point operation (with floating-point operands, not 2188947Sdlw * just results). 2198947Sdlw * 2208947Sdlw * This is complicated by the fact that the registers that will 2218947Sdlw * eventually be restored are saved in two places. registers 7-11 2228947Sdlw * are saved by this routine, and are in its call frame. (we have 2238947Sdlw * to take special care that these registers are specified in 2248947Sdlw * the procedure entry mask here.) 2258947Sdlw * Registers 0-6 are saved at interrupt time, and are at a offset 2268947Sdlw * -8 from the 'signo' parameter below. 2278947Sdlw * There is ane extremely inimate connection between the value of 2288947Sdlw * the entry mask set by the 'makefile' script, and the constants 2298947Sdlw * used in the register offset calculations below. 2308947Sdlw * Can someone think of a better way to do this? 2318947Sdlw */ 2328947Sdlw 2338947Sdlw /*ARGSUSED*/ 2348947Sdlw got_illegal_instruction(signo, codeword, myaddr, trap_pc, ps) 2358947Sdlw char *myaddr, *trap_pc; 2368947Sdlw { 2378947Sdlw int first_local[1]; /* must be first */ 2388947Sdlw int i, opcode, type, o_no, no_reserved; 2398947Sdlw anyval *opnd; 2408947Sdlw 2418947Sdlw regs7t11 = &first_local[0]; 2428947Sdlw regs0t6 = &signo - 8; 2438947Sdlw pc = trap_pc; 2448947Sdlw 2458947Sdlw opcode = fetch_byte() & 0xff; 2468947Sdlw no_reserved = 0; 24710238Sdlw if (codeword != RES_OPR_F || !is_floating_operation(opcode)) { 24810238Sdlw if (sigill_default > (SIG_VAL)7) 24910238Sdlw return((*sigill_default)(signo, codeword, myaddr, trap_pc, ps)); 25010238Sdlw else 25110238Sdlw sigdie(signo, codeword, myaddr, trap_pc, ps); 25210238Sdlw /* NOTREACHED */ 2538947Sdlw } 2548947Sdlw 2558947Sdlw if (opcode == POLYD || opcode == POLYF) { 2568947Sdlw got_illegal_poly(opcode); 2578947Sdlw return; 2588947Sdlw } 2598947Sdlw 2608947Sdlw if (opcode == EMODD || opcode == EMODF) { 2618947Sdlw got_illegal_emod(opcode); 2628947Sdlw return; 2638947Sdlw } 2648947Sdlw 2658947Sdlw /* 2668947Sdlw * This opcode wasn't "unusual". 2678947Sdlw * Look at the operands to try and find a reserved operand. 2688947Sdlw */ 2698947Sdlw for (o_no = 1; o_no <= no_operands(opcode); ++o_no) { 2708947Sdlw type = operand_type(opcode, o_no); 2718947Sdlw if (type != F && type != D) { 2728947Sdlw advance_pc(type); 2738947Sdlw continue; 2748947Sdlw } 2758947Sdlw 2768947Sdlw /* F or D operand. Check it out */ 2778947Sdlw opnd = get_operand_address(type); 2788947Sdlw if (opnd == NULL) { 2798947Sdlw fprintf(units[STDERR].ufd, "Can't get operand address: 0x%x, %d\n", 2808947Sdlw pc, o_no); 28120186Slibs f77_abort(); 2828947Sdlw } 2838947Sdlw if (type == F && opnd->o_long == 0x00008000) { 2848947Sdlw /* found one */ 2858947Sdlw opnd->o_long = retrn.v_long[0]; 2868947Sdlw ++no_reserved; 2878947Sdlw } else if (type == D && opnd->o_long == 0x00008000) { 2888947Sdlw /* found one here, too! */ 2898947Sdlw opnd->o_quad[0] = retrn.v_long[0]; 2908947Sdlw /* Fix next pointer */ 2918947Sdlw if (opnd == addr_of_reg(6)) opnd = addr_of_reg(7); 2928947Sdlw else opnd = (anyval *) ((char *) opnd + 4); 2938947Sdlw opnd->o_quad[0] = retrn.v_long[1]; 2948947Sdlw ++no_reserved; 2958947Sdlw } 2968947Sdlw 2978947Sdlw } 2988947Sdlw 2998947Sdlw if (no_reserved == 0) { 3008947Sdlw fprintf(units[STDERR].ufd, "Can't find any reserved operand!\n"); 30120186Slibs f77_abort(); 3028947Sdlw } 3038947Sdlw } 3048947Sdlw /* 3058947Sdlw * is_floating_exception - was the operation code for a floating instruction? 3068947Sdlw */ 3078947Sdlw 3088947Sdlw is_floating_operation(opcode) 3098947Sdlw int opcode; 3108947Sdlw { 3118947Sdlw switch (opcode) { 3128947Sdlw case ACBD: case ACBF: case ADDD2: case ADDD3: 3138947Sdlw case ADDF2: case ADDF3: case CMPD: case CMPF: 3148947Sdlw case CVTDB: case CVTDF: case CVTDL: case CVTDW: 3158947Sdlw case CVTFB: case CVTFD: case CVTFL: case CVTFW: 3168947Sdlw case CVTRDL: case CVTRFL: case DIVD2: case DIVD3: 3178947Sdlw case DIVF2: case DIVF3: case EMODD: case EMODF: 3188947Sdlw case MNEGD: case MNEGF: case MOVD: case MOVF: 3198947Sdlw case MULD2: case MULD3: case MULF2: case MULF3: 3208947Sdlw case POLYD: case POLYF: case SUBD2: case SUBD3: 3218947Sdlw case SUBF2: case SUBF3: case TSTD: case TSTF: 3228947Sdlw return 1; 3238947Sdlw 3248947Sdlw default: 3258947Sdlw return 0; 3268947Sdlw } 3278947Sdlw } 3288947Sdlw /* 3298947Sdlw * got_illegal_poly - handle an illegal POLY[DF] instruction. 3308947Sdlw * 3318947Sdlw * We don't do anything here yet. 3328947Sdlw */ 3338947Sdlw 3348947Sdlw /*ARGSUSED*/ 3358947Sdlw got_illegal_poly(opcode) 3368947Sdlw { 3378947Sdlw fprintf(units[STDERR].ufd, "Can't do 'poly' instructions yet\n"); 33820186Slibs f77_abort(); 3398947Sdlw } 3408947Sdlw 3418947Sdlw 3428947Sdlw 3438947Sdlw /* 3448947Sdlw * got_illegal_emod - handle illegal EMOD[DF] instruction. 3458947Sdlw * 3468947Sdlw * We don't do anything here yet. 3478947Sdlw */ 3488947Sdlw 3498947Sdlw /*ARGSUSED*/ 3508947Sdlw got_illegal_emod(opcode) 3518947Sdlw { 3528947Sdlw fprintf(units[STDERR].ufd, "Can't do 'emod' instructions yet\n"); 35320186Slibs f77_abort(); 3548947Sdlw } 3558947Sdlw 3568947Sdlw 3578947Sdlw /* 3588947Sdlw * no_operands - determine the number of operands in this instruction. 3598947Sdlw * 3608947Sdlw */ 3618947Sdlw 3628947Sdlw no_operands(opcode) 3638947Sdlw { 3648947Sdlw switch (opcode) { 3658947Sdlw case ACBD: 3668947Sdlw case ACBF: 3678947Sdlw return 3; 3688947Sdlw 3698947Sdlw case MNEGD: 3708947Sdlw case MNEGF: 3718947Sdlw case MOVD: 3728947Sdlw case MOVF: 3738947Sdlw case TSTD: 3748947Sdlw case TSTF: 3758947Sdlw return 1; 3768947Sdlw 3778947Sdlw default: 3788947Sdlw return 2; 3798947Sdlw } 3808947Sdlw } 3818947Sdlw 3828947Sdlw 3838947Sdlw 3848947Sdlw /* 3858947Sdlw * operand_type - is the operand a D or an F? 3868947Sdlw * 3878947Sdlw * We are only descriminating between Floats and Doubles here. 3888947Sdlw * Other operands may be possible on exotic instructions. 3898947Sdlw */ 3908947Sdlw 3918947Sdlw /*ARGSUSED*/ 3928947Sdlw operand_type(opcode, no) 3938947Sdlw { 3948947Sdlw if (opcode >= 0x40 && opcode <= 0x56) return F; 3958947Sdlw if (opcode >= 0x60 && opcode <= 0x76) return D; 3968947Sdlw return IDUNNO; 3978947Sdlw } 3988947Sdlw 3998947Sdlw 4008947Sdlw 4018947Sdlw /* 4028947Sdlw * advance_pc - Advance the program counter past an operand. 4038947Sdlw * 4048947Sdlw * We just bump the pc by the appropriate values. 4058947Sdlw */ 4068947Sdlw 4078947Sdlw advance_pc(type) 4088947Sdlw { 4098947Sdlw register int mode, reg; 4108947Sdlw 4118947Sdlw mode = fetch_byte(); 4128947Sdlw reg = mode & 0xf; 4138947Sdlw mode = (mode >> 4) & 0xf; 4148947Sdlw switch (mode) { 4158947Sdlw case LITERAL0: 4168947Sdlw case LITERAL1: 4178947Sdlw case LITERAL2: 4188947Sdlw case LITERAL3: 4198947Sdlw return; 4208947Sdlw 4218947Sdlw case INDEXED: 4228947Sdlw advance_pc(type); 4238947Sdlw return; 4248947Sdlw 4258947Sdlw case REGISTER: 4268947Sdlw case REG_DEF: 4278947Sdlw case AUTO_DEC: 4288947Sdlw return; 4298947Sdlw 4308947Sdlw case AUTO_INC: 4318947Sdlw if (reg == PC) { 4328947Sdlw if (type == F) (void) fetch_long(); 4338947Sdlw else if (type == D) { 4348947Sdlw (void) fetch_long(); 4358947Sdlw (void) fetch_long(); 4368947Sdlw } else { 4378947Sdlw fprintf(units[STDERR].ufd, "Bad type %d in advance\n", 4388947Sdlw type); 43920186Slibs f77_abort(); 4408947Sdlw } 4418947Sdlw } 4428947Sdlw return; 4438947Sdlw 4448947Sdlw case AUTO_INC_DEF: 4458947Sdlw if (reg == PC) (void) fetch_long(); 4468947Sdlw return; 4478947Sdlw 4488947Sdlw case BYTE_DISP: 4498947Sdlw case BYTE_DISP_DEF: 4508947Sdlw (void) fetch_byte(); 4518947Sdlw return; 4528947Sdlw 4538947Sdlw case WORD_DISP: 4548947Sdlw case WORD_DISP_DEF: 4558947Sdlw (void) fetch_word(); 4568947Sdlw return; 4578947Sdlw 4588947Sdlw case LONG_DISP: 4598947Sdlw case LONG_DISP_DEF: 4608947Sdlw (void) fetch_long(); 4618947Sdlw return; 4628947Sdlw 4638947Sdlw default: 4648947Sdlw fprintf(units[STDERR].ufd, "Bad mode 0x%x in op_length()\n", mode); 46520186Slibs f77_abort(); 4668947Sdlw } 4678947Sdlw } 4688947Sdlw 4698947Sdlw 4708947Sdlw anyval * 4718947Sdlw get_operand_address(type) 4728947Sdlw { 4738947Sdlw register int mode, reg, base; 4748947Sdlw 4758947Sdlw mode = fetch_byte() & 0xff; 4768947Sdlw reg = mode & 0xf; 4778947Sdlw mode = (mode >> 4) & 0xf; 4788947Sdlw switch (mode) { 4798947Sdlw case LITERAL0: 4808947Sdlw case LITERAL1: 4818947Sdlw case LITERAL2: 4828947Sdlw case LITERAL3: 4838947Sdlw return NULL; 4848947Sdlw 4858947Sdlw case INDEXED: 4868947Sdlw base = (int) get_operand_address(type); 4878947Sdlw if (base == NULL) return NULL; 4888947Sdlw base += contents_of_reg(reg)*type_length(type); 4898947Sdlw return (anyval *) base; 4908947Sdlw 4918947Sdlw case REGISTER: 4928947Sdlw return addr_of_reg(reg); 4938947Sdlw 4948947Sdlw case REG_DEF: 4958947Sdlw return (anyval *) contents_of_reg(reg); 4968947Sdlw 4978947Sdlw case AUTO_DEC: 4988947Sdlw return (anyval *) (contents_of_reg(reg) 4998947Sdlw - type_length(type)); 5008947Sdlw 5018947Sdlw case AUTO_INC: 5028947Sdlw return (anyval *) contents_of_reg(reg); 5038947Sdlw 5048947Sdlw case AUTO_INC_DEF: 5058947Sdlw return (anyval *) * (long *) contents_of_reg(reg); 5068947Sdlw 5078947Sdlw case BYTE_DISP: 5088947Sdlw base = fetch_byte(); 5098947Sdlw base += contents_of_reg(reg); 5108947Sdlw return (anyval *) base; 5118947Sdlw 5128947Sdlw case BYTE_DISP_DEF: 5138947Sdlw base = fetch_byte(); 5148947Sdlw base += contents_of_reg(reg); 5158947Sdlw return (anyval *) * (long *) base; 5168947Sdlw 5178947Sdlw case WORD_DISP: 5188947Sdlw base = fetch_word(); 5198947Sdlw base += contents_of_reg(reg); 5208947Sdlw return (anyval *) base; 5218947Sdlw 5228947Sdlw case WORD_DISP_DEF: 5238947Sdlw base = fetch_word(); 5248947Sdlw base += contents_of_reg(reg); 5258947Sdlw return (anyval *) * (long *) base; 5268947Sdlw 5278947Sdlw case LONG_DISP: 5288947Sdlw base = fetch_long(); 5298947Sdlw base += contents_of_reg(reg); 5308947Sdlw return (anyval *) base; 5318947Sdlw 5328947Sdlw case LONG_DISP_DEF: 5338947Sdlw base = fetch_long(); 5348947Sdlw base += contents_of_reg(reg); 5358947Sdlw return (anyval *) * (long *) base; 5368947Sdlw 5378947Sdlw default: 5388947Sdlw fprintf(units[STDERR].ufd, "Bad mode 0x%x in get_addr()\n", mode); 53920186Slibs f77_abort(); 5408947Sdlw } 5418947Sdlw return NULL; 5428947Sdlw } 5438947Sdlw 5448947Sdlw 5458947Sdlw 5468947Sdlw contents_of_reg(reg) 5478947Sdlw { 5488947Sdlw int value; 5498947Sdlw 5508947Sdlw if (reg == PC) value = (int) pc; 5518947Sdlw else if (reg == SP) value = (int) ®s0t6[6]; 5528947Sdlw else if (reg == FP) value = regs0t6[-2]; 5538947Sdlw else if (reg == AP) value = regs0t6[-3]; 5548947Sdlw else if (reg >= 0 && reg <= 6) value = regs0t6[reg]; 5558947Sdlw else if (reg >= 7 && reg <= 11) value = regs7t11[reg]; 5568947Sdlw else { 5578947Sdlw fprintf(units[STDERR].ufd, "Bad register 0x%x to contents_of()\n", reg); 55820186Slibs f77_abort(); 5598947Sdlw value = -1; 5608947Sdlw } 5618947Sdlw return value; 5628947Sdlw } 5638947Sdlw 5648947Sdlw 5658947Sdlw anyval * 5668947Sdlw addr_of_reg(reg) 5678947Sdlw { 5688947Sdlw if (reg >= 0 && reg <= 6) { 5698947Sdlw return (anyval *) ®s0t6[reg]; 5708947Sdlw } 5718947Sdlw if (reg >= 7 && reg <= 11) { 5728947Sdlw return (anyval *) ®s7t11[reg]; 5738947Sdlw } 5748947Sdlw fprintf(units[STDERR].ufd, "Bad reg 0x%x to addr_of()\n", reg); 57520186Slibs f77_abort(); 5768947Sdlw return NULL; 5778947Sdlw } 5788947Sdlw /* 5798947Sdlw * fetch_{byte, word, long} - extract values from the PROGRAM area. 5808947Sdlw * 5818947Sdlw * These routines are used in the operand decoding to extract various 5828947Sdlw * fields from where the program counter points. This is because the 5838947Sdlw * addressing on the Vax is dynamic: the program counter advances 5848947Sdlw * while we are grabbing operands, as well as when we pass instructions. 5858947Sdlw * This makes things a bit messy, but I can't help it. 5868947Sdlw */ 5878947Sdlw fetch_byte() 5888947Sdlw { 5898947Sdlw return *pc++; 5908947Sdlw } 5918947Sdlw 5928947Sdlw 5938947Sdlw 5948947Sdlw fetch_word() 5958947Sdlw { 5968947Sdlw int *old_pc; 5978947Sdlw 5988947Sdlw old_pc = (int *) pc; 5998947Sdlw pc += 2; 6008947Sdlw return *old_pc; 6018947Sdlw } 6028947Sdlw 6038947Sdlw 6048947Sdlw 6058947Sdlw fetch_long() 6068947Sdlw { 6078947Sdlw long *old_pc; 6088947Sdlw 6098947Sdlw old_pc = (long *) pc; 6108947Sdlw pc += 4; 6118947Sdlw return *old_pc; 6128947Sdlw } 61320186Slibs 6148947Sdlw 6158947Sdlw type_length(type) 6168947Sdlw { 6178947Sdlw if (type == F) return 4; 6188947Sdlw if (type == D) return 8; 6198947Sdlw fprintf(units[STDERR].ufd, "Bad type 0x%x in type_length()\n", type); 62020186Slibs f77_abort(); 6218947Sdlw return -1; 6228947Sdlw } 6238947Sdlw 6248947Sdlw 6258947Sdlw 6268947Sdlw char *opcode_name(opcode) 6278947Sdlw { 6288947Sdlw switch (opcode) { 6298947Sdlw case ACBD: return "ACBD"; 6308947Sdlw case ACBF: return "ACBF"; 6318947Sdlw case ADDD2: return "ADDD2"; 6328947Sdlw case ADDD3: return "ADDD3"; 6338947Sdlw case ADDF2: return "ADDF2"; 6348947Sdlw case ADDF3: return "ADDF3"; 6358947Sdlw case CMPD: return "CMPD"; 6368947Sdlw case CMPF: return "CMPF"; 6378947Sdlw case CVTDB: return "CVTDB"; 6388947Sdlw case CVTDF: return "CVTDF"; 6398947Sdlw case CVTDL: return "CVTDL"; 6408947Sdlw case CVTDW: return "CVTDW"; 6418947Sdlw case CVTFB: return "CVTFB"; 6428947Sdlw case CVTFD: return "CVTFD"; 6438947Sdlw case CVTFL: return "CVTFL"; 6448947Sdlw case CVTFW: return "CVTFW"; 6458947Sdlw case CVTRDL: return "CVTRDL"; 6468947Sdlw case CVTRFL: return "CVTRFL"; 6478947Sdlw case DIVD2: return "DIVD2"; 6488947Sdlw case DIVD3: return "DIVD3"; 6498947Sdlw case DIVF2: return "DIVF2"; 6508947Sdlw case DIVF3: return "DIVF3"; 6518947Sdlw case EMODD: return "EMODD"; 6528947Sdlw case EMODF: return "EMODF"; 6538947Sdlw case MNEGD: return "MNEGD"; 6548947Sdlw case MNEGF: return "MNEGF"; 6558947Sdlw case MOVD: return "MOVD"; 6568947Sdlw case MOVF: return "MOVF"; 6578947Sdlw case MULD2: return "MULD2"; 6588947Sdlw case MULD3: return "MULD3"; 6598947Sdlw case MULF2: return "MULF2"; 6608947Sdlw case MULF3: return "MULF3"; 6618947Sdlw case POLYD: return "POLYD"; 6628947Sdlw case POLYF: return "POLYF"; 6638947Sdlw case SUBD2: return "SUBD2"; 6648947Sdlw case SUBD3: return "SUBD3"; 6658947Sdlw case SUBF2: return "SUBF2"; 6668947Sdlw case SUBF3: return "SUBF3"; 6678947Sdlw case TSTD: return "TSTD"; 6688947Sdlw case TSTF: return "TSTF"; 6698947Sdlw } 6708947Sdlw } 6718947Sdlw #endif vax 672