X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=sect.c;h=ae4d750b98b84c8ed1726b4084ba39d8e6d85551;hp=7fcb2996bc30051a819e656b08f7ffa6db0b5e61;hb=ac3149e4607a5a07b212ba85a0fe44614b9aeec4;hpb=7d364a21bf389d947bb61cc235d00b3892aca89a diff --git a/sect.c b/sect.c index 7fcb299..ae4d750 100644 --- a/sect.c +++ b/sect.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // SECT.C - Code Generation, Fixups and Section Management -// Copyright (C) 199x Landon Dyer, 2011-2019 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -415,6 +415,12 @@ int ResolveFixups(int sno) // evexpr presumably issues the errors/warnings here if (evexpr(fup->expr, &eval, &eattr, &esym) != OK) continue; + + if ((CHECK_OPTS(OPT_PC_RELATIVE)) && (eattr & REFERENCED) && (eattr & DEFINED) && (!(eattr & EQUATED))) + { + error("relocation not allowed"); + continue; + } } // Simple symbol else @@ -422,6 +428,12 @@ int ResolveFixups(int sno) SYM * sy = fup->symbol; eattr = sy->sattr; + if ((CHECK_OPTS(OPT_PC_RELATIVE)) && (eattr & REFERENCED) && (eattr & DEFINED) && (!(eattr & EQUATED))) + { + error("relocation not allowed"); + continue; + } + if (eattr & DEFINED) eval = sy->svalue; else @@ -450,21 +462,24 @@ int ResolveFixups(int sno) // 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). - // // PC-relative fixups must be DEFINED and either in the same section // (whereupon the subtraction takes place) or ABS (with no subtract). - if (dw & FU_PCREL) + if ((dw & FU_PCREL) || (dw & FU_PCRELX)) { if (eattr & DEFINED) { if (tdb == sno) + { eval -= loc; + + // In this instruction the PC is located a DWORD away + if (dw & FU_PCRELX) + eval += 2; + } else if (tdb) { // Allow cross-section PCREL fixups in Alcyon mode - if (prg_flag) + if (prg_flag || (obj_format == RAW)) { switch (tdb) { @@ -483,6 +498,10 @@ int ResolveFixups(int sno) } eval -= loc; + + // In this instruction the PC is located a DWORD away + if (dw & FU_PCRELX) + eval += 2; } else { @@ -491,12 +510,11 @@ int ResolveFixups(int sno) } } - if (sbra_flag && (dw & FU_LBRA) && (eval + 0x80 < 0x100)) + if (optim_warn_flag && (dw & FU_LBRA) && (eval + 0x80 < 0x100)) warn("unoptimized short branch"); } - else if (obj_format == MWC) - eval -= loc; + // Be sure to clear any TDB flags, since we handled it just now tdb = 0; eattr &= ~TDB; } @@ -519,11 +537,15 @@ int ResolveFixups(int sno) if (eval == 0) { - if (CHECK_OPTS(OPT_NULL_BRA)) + if (*locp) // optim_flags[OPT_NULL_BRA] is stored there, check the comment in mach.s under m_br { // Just output a NOP *locp++ = 0x4E; *locp = 0x71; + + if (optim_warn_flag) + warn("bra.s with zero offset converted to NOP"); + continue; } else @@ -878,8 +900,8 @@ int ResolveFixups(int sno) locp[1] = (uint8_t)eval; break; - // This is a 6 bit absoulte short address. It occupies - // the low 6 bits of the middle byte of a DSP word. + // This is a 6 bit absoulte short address. It occupies the low 6 + // bits of the middle byte of a DSP word. case FU_DSPADR06: if (eval > 63) { @@ -890,8 +912,8 @@ int ResolveFixups(int sno) locp[1] |= eval; break; - // This is a 6 bit absoulte short address. It occupies - // the low 6 bits of the middle byte of a DSP word. + // This is a 6 bit absoulte short address. It occupies the low 6 + // bits of the middle byte of a DSP word. case FU_DSPPP06: if (eval < 0xFFFFFFC0) {