X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=riscasm.c;h=f16abe0f30d201ffda4e5c424442bac1f784399b;hb=f23a0935e11c9a1ad61e4b4ee4a1e63fbd7b3e00;hp=9ecc61da0b547fa7509b2718d707b26785cac778;hpb=c8c1bd3b363a4d796397fd4920a19fbcd98bab3a;p=rmac diff --git a/riscasm.c b/riscasm.c index 9ecc61d..f16abe0 100644 --- a/riscasm.c +++ b/riscasm.c @@ -1,7 +1,7 @@ // -// RMAC - Reboot's Macro Assembler for all Atari computers +// RMAC - Renamed Macro Assembler for all Atari computers // RISCA.C - GPU/DSP Assembler -// Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2021 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -25,6 +25,22 @@ #define MAXINTERNCC 26 // Maximum internal condition codes +// Useful macros +#define EVAL_REG_RETURN_IF_ERROR(x, y) \ +x = EvaluateRegisterFromTokenStream(y); \ +\ +if (x == ERROR) \ + return ERROR; + +#define EVAL_REG_RETURN_IF_ERROR_OR_NO_EOL(x, y) \ +x = EvaluateRegisterFromTokenStream(y); \ +\ +if ((x == ERROR) || (ErrorIfNotAtEOL() == ERROR)) \ + return ERROR; + +#define CHECK_EOL \ +if (ErrorIfNotAtEOL() == ERROR) \ + return ERROR; unsigned altbankok = 0; // Ok to use alternate register bank unsigned orgactive = 0; // RISC/6502 org directive active @@ -134,7 +150,6 @@ static const char * malformErr[] = { malform1, malform2, malform3, malform4 }; - // // Function to return "malformed expression" error // This is done mainly to remove a bunch of GOTO statements in the parser @@ -144,7 +159,6 @@ static inline int MalformedOpcode(int signal) return error("Malformed opcode, %s", malformErr[signal]); } - // // Function to return "Illegal Indexed Register" error // Anyone trying to index something other than R14 or R15 @@ -154,7 +168,6 @@ static inline int IllegalIndexedRegister(int reg) return error("Attempted index reference with non-indexable register (r%d)", reg - KW_R0); } - // // Function to return "Illegal Indexed Register" error for EQUR scenarios // Trying to use register value within EQUR that isn't 14 or 15 @@ -164,7 +177,6 @@ static inline int IllegalIndexedRegisterEqur(SYM * sy) return error("Attempted index reference with non-indexable register within EQUR (%s = r%d)", sy->sname, sy->svalue); } - // // Build up & deposit RISC instruction word // @@ -181,37 +193,68 @@ static void DepositRISCInstructionWord(uint16_t opcode, int reg1, int reg2) D_word(value); } - // // Evaluate the RISC register from the token stream. Passed in value is the // FIXUP attribute to use if the expression comes back as undefined. // -static int EvaluateRegisterFromTokenStream(uint32_t attr) +static int EvaluateRegisterFromTokenStream(uint32_t fixup) { + // Firstly, check to see if it's a register token and return that. No + // need to invoke expr() for easy cases like this. + int reg = *tok & 255; + if (reg >= KW_R0 && reg <= KW_R31) + { + // Check register bank usage in the case of .equr register + // (encoded as bits 30 and 31 in *tok). + // (I still think that this is superfluous and should be taken out, see my note in token.c) + if (*tok & 0x80000000) + { + // Oops, with all the evaluation in token.c we now lost the equated symbol reference, so we + // don't know its name or anything else. Oh well... + if ((regbank == BANK_0) && (*tok & 0x40000000) && !altbankok) + return error("equated symbol cannot be used in register bank 0"); + + if ((regbank == BANK_1) && !(*tok & 0x40000000) && !altbankok) + return error("equated symbol cannot be used in register bank 1"); + } + reg -= KW_R0; + tok++; + return reg; + } + + if (*tok != SYMBOL) + { + // If at this point we don't have a symbol then it's garbage. Punt. + return error("Expected register number or EQUREG"); + } + uint64_t eval; // Expression value WORD eattr; // Expression attributes SYM * esym; // External symbol involved in expr. TOKEN r_expr[EXPRSIZE]; // Expression token list // Evaluate what's in the global "tok" buffer + // N.B.: We should either get a fixup or a register name from EQUR if (expr(r_expr, &eval, &eattr, &esym) != OK) return ERROR; if (!(eattr & DEFINED)) { - AddFixup(FU_WORD | attr, sloc, r_expr); + AddFixup(FU_WORD | fixup, sloc, r_expr); return 0; } + // We shouldn't get here, that should not be legal + interror(9); + // If we got a register in range (0-31), return it - if (eval <= 31) - return (int)eval; + //if (eattr & RISCREG) + // return (int)eval - KW_R0; - // Otherwise, it's out of range & we flag an error - return error(reg_err); + //// Otherwise, it's out of range & we flag an error + //return error(reg_err); } - // // Do RISC code generation // @@ -230,7 +273,7 @@ int GenerateRISCCode(int state) uint64_t eval; // Expression value uint16_t eattr; // Expression attributes - SYM * esym; // External symbol involved in expr. + SYM * esym = NULL; // External symbol involved in expr. TOKEN r_expr[EXPRSIZE]; // Expression token list // Get opcode parameter and type @@ -257,8 +300,7 @@ int GenerateRISCCode(int state) // ABS, MIRROR, NEG, NOT, PACK, RESMAC, SAT8, SAT16, SAT16S, SAT24, SAT32S, // UNPACK case RI_ONE: - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); - ErrorIfNotAtEOL(); + EVAL_REG_RETURN_IF_ERROR_OR_NO_EOL(reg2, FU_REGTWO); DepositRISCInstructionWord(parm, parm >> 6, reg2); break; @@ -269,14 +311,13 @@ int GenerateRISCCode(int state) if (parm == 37) altbankok = 1; // MOVEFA - reg1 = EvaluateRegisterFromTokenStream(FU_REGONE); + EVAL_REG_RETURN_IF_ERROR(reg1, FU_REGONE); CHECK_COMMA; if (parm == 36) altbankok = 1; // MOVETA - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); - ErrorIfNotAtEOL(); + EVAL_REG_RETURN_IF_ERROR_OR_NO_EOL(reg2, FU_REGTWO); DepositRISCInstructionWord(parm, reg1, reg2); break; @@ -343,8 +384,7 @@ int GenerateRISCCode(int state) } CHECK_COMMA; - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); - ErrorIfNotAtEOL(); + EVAL_REG_RETURN_IF_ERROR_OR_NO_EOL(reg2, FU_REGTWO); DepositRISCInstructionWord(parm, reg1, reg2); break; @@ -392,8 +432,7 @@ int GenerateRISCCode(int state) } CHECK_COMMA; - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); - ErrorIfNotAtEOL(); + EVAL_REG_RETURN_IF_ERROR_OR_NO_EOL(reg2, FU_REGTWO); DepositRISCInstructionWord(parm, 0, reg2); val = WORDSWAP32(eval); @@ -411,12 +450,11 @@ int GenerateRISCCode(int state) else { parm = 34; - reg1 = EvaluateRegisterFromTokenStream(FU_REGONE); + EVAL_REG_RETURN_IF_ERROR(reg1, FU_REGONE); } CHECK_COMMA; - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); - ErrorIfNotAtEOL(); + EVAL_REG_RETURN_IF_ERROR_OR_NO_EOL(reg2, FU_REGTWO); DepositRISCInstructionWord(parm, reg1, reg2); break; @@ -433,39 +471,42 @@ int GenerateRISCCode(int state) if ((tok[1] == '+') || (tok[1] == '-')) { // Trying to make indexed call - if ((*tok == KW_R14) || (*tok == KW_R15)) - indexed = (*tok - KW_R0); + // Note: no bank check for .equr symbol here, but the original code for .equr + // below also didn't check for banks. Even more reasons to throw away + // bank checks. + if (((*tok & 0xff) == KW_R14) || ((*tok &0xff) == KW_R15)) + indexed = ((*tok & 0xff) - KW_R0); else return IllegalIndexedRegister(*tok); } - if (*tok == SYMBOL) - { - sy = lookup(string[tok[1]], LABEL, 0); - - if (!sy) - { - error(reg_err); - return ERROR; - } - - if (sy->sattre & EQUATEDREG) - { - if ((tok[2] == '+') || (tok[2] == '-')) - { - if ((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15) { - indexed = (sy->svalue & 0x1F); - tok++; - } - else - return IllegalIndexedRegisterEqur(sy); - } - } - } + //if (*tok == SYMBOL) + //{ + // sy = lookup(string[tok[1]], LABEL, 0); + // + // if (!sy) + // { + // error(reg_err); + // return ERROR; + // } + // + // if (sy->sattre & EQUATEDREG) + // { + // if ((tok[2] == '+') || (tok[2] == '-')) + // { + // if ((sy->svalue - KW_R0) == 14 || (sy->svalue - KW_R0) == 15) { + // indexed = (sy->svalue - KW_R0); + // tok++; + // } + // else + // return IllegalIndexedRegisterEqur(sy); + // } + // } + //} if (!indexed) { - reg1 = EvaluateRegisterFromTokenStream(FU_REGONE); + EVAL_REG_RETURN_IF_ERROR(reg1, FU_REGONE); } else { @@ -478,7 +519,7 @@ int GenerateRISCCode(int state) parm = (WORD)(reg1 - 14 + 58); tok++; - if ((*tok >= KW_R0) && (*tok <= KW_R31)) + if (((*tok & 0xff) >= KW_R0) && ((*tok & 0xff) <= KW_R31)) indexed = 1; if (*tok == SYMBOL) @@ -497,7 +538,7 @@ int GenerateRISCCode(int state) if (indexed) { - reg1 = EvaluateRegisterFromTokenStream(FU_REGONE); + EVAL_REG_RETURN_IF_ERROR(reg1, FU_REGONE); } else { @@ -529,7 +570,7 @@ int GenerateRISCCode(int state) } else { - reg1 = EvaluateRegisterFromTokenStream(FU_REGONE); + EVAL_REG_RETURN_IF_ERROR(reg1, FU_REGONE); } } @@ -538,15 +579,14 @@ int GenerateRISCCode(int state) tok++; CHECK_COMMA; - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); - ErrorIfNotAtEOL(); + EVAL_REG_RETURN_IF_ERROR_OR_NO_EOL(reg2, FU_REGTWO); DepositRISCInstructionWord(parm, reg1, reg2); break; // Rn,(Rn) = 47 / Rn,(R14/R15+n) = 49/50 / Rn,(R14/R15+Rn) = 60/61 case RI_STORE: parm = 47; - reg1 = EvaluateRegisterFromTokenStream(FU_REGONE); + EVAL_REG_RETURN_IF_ERROR(reg1, FU_REGONE); CHECK_COMMA; if (*tok != '(') @@ -555,33 +595,35 @@ int GenerateRISCCode(int state) tok++; indexed = 0; - if (((*tok == KW_R14) || (*tok == KW_R15)) && (tok[1] != ')')) - indexed = *tok - KW_R0; - - if (*tok == SYMBOL) - { - sy = lookup(string[tok[1]], LABEL, 0); - - if (!sy) - { - error(reg_err); - return ERROR; - } - - if (sy->sattre & EQUATEDREG) - { - if (((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15) - && (tok[2] != ')')) - { - indexed = (sy->svalue & 0x1F); - tok++; - } - } - } + // Again, no bank checks here or in the original code. + // This check has more holes than a very hole-y thing. + if ((((*tok & 0xff) == KW_R14) || ((*tok & 0xff) == KW_R15)) && (tok[1] != ')')) + indexed = (*tok & 0xff) - KW_R0; + + //if (*tok == SYMBOL) + //{ + // sy = lookup(string[tok[1]], LABEL, 0); + // + // if (!sy) + // { + // error(reg_err); + // return ERROR; + // } + // + // if (sy->sattre & EQUATEDREG) + // { + // if (((sy->svalue - KW_R0) == 14 || (sy->svalue - KW_R0) == 15) + // && (tok[2] != ')')) + // { + // indexed = (sy->svalue - KW_R0); + // tok++; + // } + // } + //} if (!indexed) { - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); + EVAL_REG_RETURN_IF_ERROR(reg2, FU_REGTWO); } else { @@ -594,7 +636,7 @@ int GenerateRISCCode(int state) parm = (WORD)(reg2 - 14 + 60); tok++; - if ((*tok >= KW_R0) && (*tok <= KW_R31)) + if (((*tok & 0xff) >= KW_R0) && ((*tok & 0xff) <= KW_R31)) indexed = 1; if (*tok == SYMBOL) @@ -613,7 +655,7 @@ int GenerateRISCCode(int state) if (indexed) { - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); + EVAL_REG_RETURN_IF_ERROR(reg2, FU_REGTWO); } else { @@ -650,7 +692,7 @@ int GenerateRISCCode(int state) } else { - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); + EVAL_REG_RETURN_IF_ERROR(reg2, FU_REGTWO); } } @@ -658,7 +700,7 @@ int GenerateRISCCode(int state) return MalformedOpcode(MALF_RPAREN); tok++; - ErrorIfNotAtEOL(); + CHECK_EOL; DepositRISCInstructionWord(parm, reg2, reg1); break; @@ -668,34 +710,33 @@ int GenerateRISCCode(int state) return MalformedOpcode(MALF_LPAREN); tok++; - reg1 = EvaluateRegisterFromTokenStream(FU_REGONE); + EVAL_REG_RETURN_IF_ERROR(reg1, FU_REGONE); if (*tok != ')') return MalformedOpcode(MALF_RPAREN); tok++; CHECK_COMMA; - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); - ErrorIfNotAtEOL(); + EVAL_REG_RETURN_IF_ERROR_OR_NO_EOL(reg2, FU_REGTWO); DepositRISCInstructionWord(parm, reg1, reg2); break; // STOREB/STOREP/STOREW Rn,(Rn) case RI_STOREN: - reg1 = EvaluateRegisterFromTokenStream(FU_REGONE); + EVAL_REG_RETURN_IF_ERROR(reg1, FU_REGONE); CHECK_COMMA; if (*tok != '(') return MalformedOpcode(MALF_LPAREN); tok++; - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); + EVAL_REG_RETURN_IF_ERROR(reg2, FU_REGTWO); if (*tok != ')') return MalformedOpcode(MALF_RPAREN); tok++; - ErrorIfNotAtEOL(); + CHECK_EOL; DepositRISCInstructionWord(parm, reg2, reg1); break; @@ -802,13 +843,13 @@ int GenerateRISCCode(int state) return MalformedOpcode(MALF_LPAREN); tok++; - reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO); + EVAL_REG_RETURN_IF_ERROR(reg2, FU_REGTWO); if (*tok != ')') return MalformedOpcode(MALF_RPAREN); tok++; - ErrorIfNotAtEOL(); + CHECK_EOL; } DepositRISCInstructionWord(parm, reg2, reg1); @@ -822,4 +863,3 @@ int GenerateRISCCode(int state) lastOpcode = type; return 0; } -