home *** CD-ROM | disk | FTP | other *** search
- /*
- (C) Copyright Taiichi Yuasa and Masami Hagiya, 1984. All rights reserved.
- */
-
- /*
- fasl_reloc.c
- DG-SPECIFIC
-
- fasl relocation routines
- */
-
- #include <stdio.h>
- #include "../h/fasl.h"
- #include "../h/fasl_global.h"
- #include "../h/fasl_reloc.h"
-
- int fas_base; /* base */
- int fas_dword; /* data word */
- int fas_pc; /* program counter */
- int fas_result; /* result */
-
- bit_relocation(reloc, bit_p, dword_p)
- short reloc; /* extended relocation */
- FAS_BIT_P bit_p; /* bit dictionary pointer */
- short *dword_p; /* dictionaried word pointer */
- {
-
- }
-
- relocation(reloc, base_p, dword_p)
- short reloc; /* extended relocation */
- short *base_p; /* base pointer */
- short *dword_p; /* dictionaried word pointer */
- {
- short base_no; /* base no */
-
- if (reloc < RL_ADDR_WORD_32_31)
- FEerror("Illegal relocation.", 0);
-
- base_no = *base_p; /* get base */
-
- if (fas_relocation_by_table == TRUE) {
- part_table_p = fasl_get_table(base_no);
- fas_base = part_table_p->part_addr;
- } else
- fas_base = fasl_get_addr(base_no);
- if (reloc > RL_DATA_SUB2_32_32)
- fas_dword = *dword_p; /* 16 bits data word */
- else
- fas_dword = *((int *)dword_p); /* 32 bits data word */
- fas_pc = dword_p;
-
- switch(reloc) {
-
- case RL_ADDR_WORD_32_31: addr_word_32_31();
- break;
- case RL_ADDR_BYTE_32_31: addr_byte_32_31();
- break;
- case RL_ADDR_PC_REL_32_31: addr_pc_rel_32_31();
- break;
- case RL_ADDR_PC_BYTE_32_31: addr_pc_byte_32_31();
- break;
- case RL_ADDR_WORD_32_28: addr_word_32_28();
- break;
- case RL_ADDR_BYTE_32_28: addr_byte_32_28();
- break;
- case RL_ADDR_PC_REL_32_28: addr_pc_rel_32_28();
- break;
- case RL_ADDR_PC_BYTE_32_28: addr_pc_byte_32_28();
- break;
- case RL_ADDR_WORD_28_31: addr_word_28_31();
- break;
- case RL_ADDR_BYTE_28_31: addr_byte_28_31();
- break;
- case RL_ADDR_PC_REL_28_31: addr_pc_rel_28_31();
- break;
- case RL_ADDR_PC_BYTE_28_31: addr_pc_byte_28_31();
- break;
- case RL_DATA_ADD_32_32: data_add_32_32();
- break;
- case RL_DATA_SUB1_32_32: data_sub1_32_32();
- break;
- case RL_DATA_MUL_32_32: data_mul_32_32();
- break;
- case RL_DATA_SUB2_32_32: data_sub2_32_32();
- break;
- case RL_DATA_ADD_32_16S: data_add_32_16s();
- break;
- case RL_DATA_SUB1_32_16S: data_sub1_32_16s();
- break;
- case RL_DATA_MUL_32_16S: data_mul_32_16s();
- break;
- case RL_DATA_SUB2_32_16S: data_sub2_32_16s();
- break;
- case RL_DATA_ADD_32_16U: data_add_32_16u();
- break;
- case RL_DATA_SUB1_32_16U: data_sub1_32_16u();
- break;
- case RL_DATA_MUL_32_16U: data_mul_32_16u();
- break;
- case RL_DATA_SUB2_32_16U: data_sub2_32_16u();
- break;
- case RL_DATA_ADD_32_16: data_add_32_16();
- break;
- case RL_DATA_SUB1_32_16: data_sub1_32_16();
- break;
- case RL_DATA_MUL_32_16: data_mul_32_16();
- break;
- case RL_DATA_SUB2_32_16: data_sub2_32_16();
- break;
- case RL_ADDR_WORD_32_15U: addr_word_32_15u();
- break;
- case RL_ADDR_BYTE_32_15U: addr_byte_32_15u();
- break;
- case RL_ADDR_PC_REL_32_15U: addr_pc_rel_32_15u();
- break;
- case RL_ADDR_PC_BYTE_32_15U: addr_pc_byte_32_15u();
- break;
- case RL_ADDR_WORD_32_15S: addr_word_32_15s();
- break;
- case RL_ADDR_BYTE_32_15S: addr_byte_32_15s();
- break;
- case RL_ADDR_PC_REL_32_15S: addr_pc_rel_32_15s();
- break;
- case RL_ADDR_PC_BYTE_32_15S: addr_pc_byte_32_15s();
- break;
- default: unexpect_reloc(reloc);
- break;
- } /* end of switch */
-
- if (reloc > RL_DATA_SUB2_32_32)
- *dword_p = fas_result & LOW16_BITS; /* 16 bits */
- else
- *((int *)dword_p) = fas_result; /* 32 bits */
- }
- addr_word_32_31()
- {
- int indirect;
-
- indirect = fas_dword & INDIRECT_BIT;
- fas_dword &= LOW31_BITS;
- fas_result = fas_base + fas_dword;
- fas_result = indirect | (fas_result & LOW31_BITS);
- }
-
- addr_byte_32_31()
- {
- fas_result = fas_base * 2 + fas_dword;
- }
-
- addr_pc_rel_32_31()
- {
- int indirect;
-
- indirect = fas_dword & INDIRECT_BIT;
- fas_dword &= LOW31_BITS;
- fas_pc &= LOW28_BITS;
- fas_result = fas_base + fas_dword;
- fas_result = (fas_result - fas_pc) | indirect;
- }
-
- addr_pc_byte_32_31()
- {
- fas_result = fas_base * 2 + fas_dword;
- fas_result -= (fas_pc & LOW28_BITS);
- }
-
- addr_word_32_28()
- {
- int ring;
-
- ring = fas_dword & RING_BITS;
- fas_result = fas_base + (fas_dword & LOW28_BITS);
- if ((fas_result < 0) |
- (fas_result >= 02000000000))
- rloverflow();
- fas_result |= ring;
- }
-
- addr_byte_32_28()
- {
- int ring;
-
- ring = fas_dword & RING_BITS;
- fas_result = fas_base + 2 * (fas_dword & LOW28_BITS);
- if ((fas_result < 0) |
- (fas_result >= 04000000000))
- rloverflow();
- fas_result |= (2 * ring);
- }
-
- addr_pc_rel_32_28()
- {
- int indirect;
-
- fas_pc &= LOW28_BITS;
- indirect = fas_dword & INDIRECT_BIT;
- fas_result = fas_base + (fas_dword & LOW28_BITS);
- if ((fas_result < 0) |
- (fas_result >= 2000000000))
- rloverflow();
- fas_result = ((fas_result - fas_pc) & LOW31_BITS) | indirect;
- }
-
- addr_pc_byte_32_28()
- {
- fas_result = fas_base + 2 * (fas_dword | LOW28_BITS);
- if ((fas_result < 0) |
- (fas_result >= 04000000000))
- rloverflow();
- fas_result -= 2 * fas_pc;
- }
-
- addr_word_28_31()
- {
- int ring, indirect;
-
- ring = fas_base & RING_BITS;
- fas_base &= LOW28_BITS;
- indirect = fas_dword & INDIRECT_BIT;
- fas_dword &= LOW31_BITS;
- fas_result = fas_base + fas_dword;
- if ((fas_result < 0) |
- (fas_result >= 02000000000))
- rloverflow();
- fas_result = indirect | ring | fas_result;
- }
-
- addr_byte_28_31()
- {
- int ring;
-
- ring = fas_base & RING_BITS;
- fas_base &= LOW28_BITS;
- fas_result = 2 * fas_base + fas_dword;
- if ((fas_result < 0) |
- (fas_result >= 04000000000))
- rloverflow();
- fas_result |= ring * 2;
- }
-
- addr_pc_rel_28_31()
- {
- int indirect;
-
- indirect = fas_dword & INDIRECT_BIT;
- fas_base &= LOW28_BITS;
- fas_dword &= LOW31_BITS;
- fas_pc &= LOW28_BITS;
- fas_result = fas_base + fas_dword;
- if ((fas_result < 0) |
- (fas_result >= 02000000000))
- rloverflow();
- fas_result = ((fas_result - fas_pc) & LOW31_BITS) | indirect;
- }
-
- addr_pc_byte_28_31()
- {
- fas_base &= LOW28_BITS;
- fas_pc &= LOW28_BITS;
- fas_result = 2 * fas_base + fas_dword;
- if ((fas_result < 0) |
- (fas_result >= 04000000000))
- rloverflow();
- fas_result -= 2 * fas_pc;
- }
-
- data_add_32_32()
- {
- fas_result = fas_base + fas_dword;
- }
-
- data_sub1_32_32()
- {
- fas_result = fas_base - fas_dword;
- }
-
- data_mul_32_32()
- {
- fas_result = fas_base * fas_dword;
- }
-
- data_sub2_32_32()
- {
- fas_result = fas_dword - fas_base;
- }
-
- data_add_32_16s()
- {
- fas_result = fas_base + fas_dword;
- if ((fas_result < -0100000) |
- (fas_result >= 0100000))
- rloverflow();
- }
-
- data_sub1_32_16s()
- {
- fas_result = fas_base - fas_dword;
- if ((fas_result < -100000) |
- (fas_result >= 0100000))
- rloverflow();
- }
-
- data_mul_32_16s()
- {
- fas_result = fas_base * fas_dword;
- if ((fas_result < -0100000) |
- (fas_result >= 0100000))
- rloverflow();
- }
-
- data_sub2_32_16s()
- {
- fas_result = fas_dword - fas_base;
- if ((fas_result < -0100000) |
- (fas_result >= 0100000))
- rloverflow();
- }
-
- data_add_32_16u()
- {
- data_16u();
- fas_result = fas_base + fas_dword;
- if ((fas_result < 0) |
- (fas_result >= 0200000))
- rloverflow();
- }
-
- data_sub1_32_16u()
- {
- data_16u();
- fas_result = fas_base - fas_dword;
- if ((fas_result < 0) |
- (fas_result >= 0200000))
- rloverflow();
- }
-
- data_mul_32_16u()
- {
- data_16u();
- fas_result = fas_base * fas_dword;
- if ((fas_result < 0) |
- (fas_result >= 0200000))
- rloverflow();
- }
-
- data_sub2_32_16u()
- {
- data_16u();
- fas_result = fas_dword - fas_base;
- if ((fas_result < 0) |
- (fas_result >= 0200000))
- rloverflow();
- }
-
- data_add_32_16()
- {
- data_16u();
- fas_result = fas_base + fas_dword;
- }
-
- data_sub1_32_16()
- {
- data_16u();
- fas_result = fas_base - fas_dword;
- }
-
- data_mul_32_16()
- {
- data_16u();
- fas_result = fas_base * fas_dword;
- }
-
- data_sub2_32_16()
- {
- data_16u();
- fas_result = fas_dword - fas_base;
- }
- addr_word_32_15u()
- {
-
- int high_4bits;
-
- high_4bits = fas_dword & HIGH4_BITS16;
- data_15u(); /* 15 bits unsigned */
- fas_dword &= LOW15_BITS;
- fas_base &= LOW28_BITS;
- fas_result = fas_base + fas_dword;
- if ((fas_result < 0) ||
- (fas_result >= 0100000))
- rloverflow();
- fas_result = (high_4bits | fas_result) & LOW16_BITS;
- }
-
- addr_byte_32_15u()
- {
- fas_base &= LOW28_BITS;
- fas_result = 2 * fas_base + fas_dword;
- if ((fas_result < 0) |
- (fas_result >= 0200000))
- rloverflow();
- fas_result &= LOW8_BITS;
- }
-
- addr_pc_rel_32_15u()
- {
- int indirect;
-
- indirect = fas_dword & INDIRECT_BIT16;
- data_15u();
- fas_base &= LOW28_BITS;
- fas_pc &= LOW28_BITS;
- fas_result = fas_base - fas_pc + fas_dword;
- if ((fas_result < 0) |
- (fas_result >= 0100000))
- rloverflow();
- fas_result |= indirect;
- }
-
- addr_pc_byte_32_15u()
- {
- fas_base &= LOW28_BITS;
- fas_pc &= LOW28_BITS;
- fas_result = 2 * fas_base + 2 * fas_pc + fas_dword;
- if ((fas_result < 0) |
- (fas_result >= 0200000))
- rloverflow();
- fas_result &= LOW8_BITS;
- }
-
- addr_word_32_15s()
- {
- int indirect;
-
- indirect = fas_dword & INDIRECT_BIT16;
- data_15s();
- fas_base &= LOW28_BITS;
- fas_result = fas_base + fas_dword;
- if ((fas_result < -040000) |
- (fas_result >= 040000))
- rloverflow();
- fas_result = (fas_result & LOW15_BITS) | indirect;
- }
-
- addr_byte_32_15s()
- {
- fas_base &= LOW28_BITS;
- fas_result = 2 * fas_base + fas_dword;
- if ((fas_result < -0100000) |
- (fas_result >= 0100000))
- rloverflow();
- }
-
- addr_pc_rel_32_15s()
- {
- int indirect;
-
- indirect = fas_dword & INDIRECT_BIT16;
- data_15s();
- fas_base &= LOW28_BITS;
- fas_pc &= LOW28_BITS;
- fas_result = fas_base + fas_pc - fas_dword;
- if ((fas_result < -040000) |
- (fas_result >= 040000))
- rloverflow();
- fas_result = (fas_result & LOW15_BITS) | indirect;
- }
-
- addr_pc_byte_32_15s()
- {
- fas_base &= LOW28_BITS;
- fas_pc &= LOW28_BITS;
- fas_result = 2 * fas_base - 2 * fas_pc + fas_dword;
- if ((fas_result < -010000) |
- (fas_result >= 010000))
- rloverflow();
- fas_result &= LOW8_BITS;
- }
- data_15u()
- {
- fas_dword &= LOW15_BITS;
- }
-
- data_15s()
- {
- if ((fas_dword & BIT_17) != 0)
- fas_dword |= ( ~LOW15_BITS);
- else
- fas_dword &= LOW15_BITS;
- }
-
- data_16u()
- {
- fas_dword &= LOW16_BITS;
- }
-
- rloverflow()
- {
- FEerror("Relocation overflow.", 0);
- }
- unexpect_reloc(reloc)
- short reloc;
- {
- FEerror("Unexpected relocation.", 0);
- }
-