X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=sect.c;h=59f7977160b11dee3d3057e050f166f426bc74ea;hp=f4ce7889e1f6a65a6ee5b11f28d8e01488c803f7;hb=66b362fa203d0850e8dce8045adb454e354c22ce;hpb=9153334781cd2e23750f4dc002e847606c07a1f0 diff --git a/sect.c b/sect.c index f4ce788..59f7977 100644 --- a/sect.c +++ b/sect.c @@ -177,26 +177,26 @@ int fixtest(int sno, uint32_t loc) // // Check that there are at least 'amt' bytes left in the current chunk. If -// there are not, allocate another chunk of at least 'amt' bytes (and probably -// more). +// there are not, allocate another chunk of at least CH_CODE_SIZE bytes or +// 'amt', whichever is larger. // // If 'amt' is zero, ensure there are at least CH_THRESHOLD bytes, likewise. // -int chcheck(uint32_t amt) +void chcheck(uint32_t amt) { DEBUG { printf("chcheck(%u)\n", amt); } // If in BSS section, no allocation required if (scattr & SBSS) - return 0; + return; - if (!amt) + if (amt == 0) amt = CH_THRESHOLD; - DEBUG { printf(" challoc=%i, ch_size=%i, diff=%i\n", challoc, ch_size, challoc-ch_size); } + DEBUG { printf(" challoc=%i, ch_size=%i, diff=%i\n", challoc, ch_size, challoc - ch_size); } if ((int)(challoc - ch_size) >= (int)amt) - return 0; + return; if (amt < CH_CODE_SIZE) amt = CH_CODE_SIZE; @@ -216,7 +216,7 @@ int chcheck(uint32_t amt) { cp->chprev = scode; scode->chnext = cp; - scode->ch_size = ch_size; // Save old chunk's globals + scode->ch_size = ch_size; // Save old chunk's globals } // Setup chunk and global vars @@ -227,7 +227,7 @@ int chcheck(uint32_t amt) chptr = cp->chptr = ((uint8_t *)cp) + sizeof(CHUNK); scode = p->scode = cp; - return 0; + return; } @@ -290,7 +290,7 @@ int AddFixup(uint32_t attr, uint32_t loc, TOKEN * fexpr) DEBUG { printf("AddFixup: sno=%u, l#=%u, attr=$%X, loc=$%X, expr=%p, sym=%p, org=$%X\n", cursect, fixup->lineno, fixup->attr, fixup->loc, (void *)fixup->expr, (void *)fixup->symbol, fixup->orgaddr); if (symbol != NULL) - printf(" name: %s, value: $lX\n", symbol->sname, symbol->svalue); + printf(" name: %s, value: $%lX\n", symbol->sname, symbol->svalue); } return 0; @@ -298,14 +298,10 @@ int AddFixup(uint32_t attr, uint32_t loc, TOKEN * fexpr) // -// Resolve fixups in a section +// Resolve fixups in the passed in section // int ResolveFixups(int sno) { - uint64_t eval; // Expression value - int reg2; - uint16_t flags; - SECT * sc = §[sno]; // "Cache" first chunk @@ -328,7 +324,7 @@ int ResolveFixups(int sno) FIXUP * fup = fixup; fixup = fixup->next; - uint32_t w = fup->attr; // Fixup long (type+modes+flags) + uint32_t w = fup->attr; // Fixup long (type + modes + flags) uint32_t loc = fup->loc; // Location to fixup cfileno = fup->fileno; curlineno = fup->lineno; @@ -365,8 +361,11 @@ int ResolveFixups(int sno) // subtract the chunk's starting location from loc to get the offset // into the current chunk. uint8_t * locp = cch->chptr + (loc - cch->chloc); + uint16_t eattr = 0; // Expression attrib SYM * esym = NULL; // External symbol involved in expr + uint64_t eval; // Expression value + uint16_t flags; // Mark flags // Compute expression/symbol value and attributes @@ -404,17 +403,15 @@ int ResolveFixups(int sno) // Do the fixup // - // If a PC-relative fixup is undefined, its value is *not* - // subtracted from the location (that will happen in the linker - // when the external reference is resolved). + // If a PC-relative fixup is undefined, its value is *not* subtracted + // from the location (that will happen in the linker when the external + // reference is resolved). // - // MWC expects PC-relative things to have the LOC subtracted from - // the value, if the value is external (that is, undefined at this - // point). + // MWC expects PC-relative things to have the LOC subtracted from the + // value, if the value is external (that is, undefined at this point). // - // PC-relative fixups must be DEFINED and either in the same - // section (whereupon the subtraction takes place) or ABS (with no - // subtract). + // PC-relative fixups must be DEFINED and either in the same section + // (whereupon the subtraction takes place) or ABS (with no subtract). if (w & FU_PCREL) { if (eattr & DEFINED) @@ -537,7 +534,7 @@ int ResolveFixups(int sno) continue; } - *locp = (uint8_t)((eval >> 8) & 0xFF); + *locp = (uint8_t)(eval >> 8); break; case FU_BYTEL: @@ -547,61 +544,63 @@ int ResolveFixups(int sno) continue; } - *locp = (uint8_t)(eval & 0xFF); + *locp = (uint8_t)eval; break; - // Fixup WORD forward references; the word could be unaligned in - // the section buffer, so we have to be careful. + // Fixup WORD forward references; the word could be unaligned in the + // section buffer, so we have to be careful. case FU_WORD: if ((w & FUMASKRISC) == FU_JR) { + int reg; + if (fup->orgaddr) - reg2 = (signed)((eval - (fup->orgaddr + 2)) / 2); + reg = (signed)((eval - (fup->orgaddr + 2)) / 2); else - reg2 = (signed)((eval - (loc + 2)) / 2); + reg = (signed)((eval - (loc + 2)) / 2); - if ((reg2 < -16) || (reg2 > 15)) + if ((reg < -16) || (reg > 15)) { error("relative jump out of range"); break; } - *locp = (uint8_t)(*locp | ((reg2 >> 3) & 0x03)); + *locp |= ((uint8_t)reg >> 3) & 0x03; locp++; - *locp = (uint8_t)(*locp | ((reg2 & 0x07) << 5)); + *locp |= ((uint8_t)reg & 0x07) << 5; break; } else if ((w & FUMASKRISC) == FU_NUM15) { - if (eval < -16 || eval > 15) + if (((int)eval < -16) || ((int)eval > 15)) { - error("constant out of range"); + error("constant out of range (-16 - +15)"); break; } - *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); + *locp |= ((uint8_t)eval >> 3) & 0x03; locp++; - *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + *locp |= ((uint8_t)eval & 0x07) << 5; break; } else if ((w & FUMASKRISC) == FU_NUM31) { if (eval > 31) { - error("constant out of range"); + error("constant out of range (0-31)"); break; } - *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); + *locp |= ((uint8_t)eval >> 3) & 0x03; locp++; - *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + *locp |= ((uint8_t)eval & 0x07) << 5; break; } else if ((w & FUMASKRISC) == FU_NUM32) { - if (eval < 1 || eval > 32) + if ((eval < 1) || (eval > 32)) { - error("constant out of range"); + error("constant out of range (1-32)"); break; } @@ -609,34 +608,34 @@ int ResolveFixups(int sno) eval = (32 - eval); eval = (eval == 32) ? 0 : eval; - *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); + *locp |= ((uint8_t)eval >> 3) & 0x03; locp++; - *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + *locp |= ((uint8_t)eval & 0x07) << 5; break; } else if ((w & FUMASKRISC) == FU_REGONE) { if (eval > 31) { - error("register value out of range"); + error("register one value out of range"); break; } - *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); + *locp |= ((uint8_t)eval >> 3) & 0x03; locp++; - *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + *locp |= ((uint8_t)eval & 0x07) << 5; break; } else if ((w & FUMASKRISC) == FU_REGTWO) { if (eval > 31) { - error("register value out of range"); + error("register two value out of range"); break; } locp++; - *locp = (uint8_t)(*locp | (eval & 0x1F)); + *locp |= (uint8_t)eval & 0x1F; break; } @@ -680,9 +679,8 @@ int ResolveFixups(int sno) break; - // Fixup LONG forward references; - // the long could be unaligned in the section buffer, so be careful - // (again). + // Fixup LONG forward references; the long could be unaligned in the + // section buffer, so be careful (again). case FU_LONG: flags = MLONG; @@ -703,6 +701,38 @@ int ResolveFixups(int sno) SETBE32(locp, 0, eval); break; + // Fixup QUAD forward references (mainly used by the OP assembler) + case FU_QUAD: + if (w & FU_OBJLINK) + { + uint64_t quad = GETBE64(locp, 0); + uint64_t addr = eval; + + if (fup->orgaddr) + addr = fup->orgaddr; + + + eval = (quad & 0xFFFFFC0000FFFFFFLL) | ((addr & 0x3FFFF8) << 21); + } + else if (w & FU_OBJDATA) + { + // If it's in a TEXT or DATA section, be sure to mark for a + // fixup later + if (tdb) + MarkRelocatable(sno, loc, tdb, MQUAD, NULL); + + uint64_t quad = GETBE64(locp, 0); + uint64_t addr = eval; + + if (fup->orgaddr) + addr = fup->orgaddr; + + eval = (quad & 0x000007FFFFFFFFFFLL) | ((addr & 0xFFFFF8) << 40); + } + + SETBE64(locp, 0, eval); + break; + // Fixup a 3-bit "QUICK" reference in bits 9..1 // (range of 1..8) in a word. [Really bits 1..3 in a byte.] case FU_QUICK: @@ -728,6 +758,21 @@ int ResolveFixups(int sno) *locp = (uint8_t)eval; break; + // Fixup a 4-byte float + case FU_FLOATSING: + warn("FU_FLOATSING missing implementation\n%s", "And you may ask yourself, \"Self, how did I get here?\""); + break; + + // Fixup a 8-byte float + case FU_FLOATDOUB: + warn("FU_FLOATDOUB missing implementation\n%s", "And you may ask yourself, \"Self, how did I get here?\""); + break; + + // Fixup a 12-byte float + case FU_FLOATEXT: + warn("FU_FLOATEXT missing implementation\n%s", "And you may ask yourself, \"Self, how did I get here?\""); + break; + default: // Bad fixup type--this should *never* happen! // Once we call this function, it winds down immediately; it