{ 2, "Symbol `%s' is defined but never used" },
{ 2, "Symbol `%s' is imported but never used" },
{ 1, "Cannot track processor status byte" },
+ { 1, "Suspicious address expression" },
{ 0, "User warning: %s" },
};
#include "global.h"
#include "nexttok.h"
#include "objcode.h"
+#include "symtab.h"
#include "instr.h"
* modes.
*/
if (Expr && (AddrModeSet & AM_ZP) && !IsByteExpr (Expr)) {
- AddrModeSet &= ~AM_ZP;
+ AddrModeSet &= ~AM_ZP;
}
/* Check if we have any adressing modes left */
if (AddrModeSet == 0) {
- Error (ERR_ILLEGAL_ADDR_MODE);
- return;
+ Error (ERR_ILLEGAL_ADDR_MODE);
+ return;
}
AddrMode = BitFind (AddrModeSet);
+ /* If the instruction has a one byte operand and immediate addressing is
+ * allowed but not used, check for an operand expression in the form
+ * <label or >label, where label is a far or absolute label. If found,
+ * emit a warning. This warning protects against a typo, where the '#'
+ * for the immediate operand is omitted.
+ */
+ if (Expr && (Ins->AddrMode & AM_IMM) &&
+ (AddrModeSet & (AM_DIR | AM_ABS | AM_ABS_LONG)) &&
+ ExtBytes[AddrMode] == 1) {
+
+ /* Found, check the expression */
+ ExprNode* Left = Expr->Left;
+ if ((Expr->Op == EXPR_BYTE0 || Expr->Op == EXPR_BYTE1) &&
+ Left->Op == EXPR_SYMBOL &&
+ !SymIsZP (Left->V.Sym)) {
+
+ /* Output a warning */
+ Warning (WARN_SUSPICIOUS_ADDREXPR);
+ }
+ }
+
/* Build the opcode */
OpCode = Ins->BaseCode | EATab [Ins->ExtCode][AddrMode];
/* Check how many extension bytes are needed and output the instruction */
- switch (ExtBytes [AddrMode]) {
+ switch (ExtBytes[AddrMode]) {
case 0:
Emit0 (OpCode);
* mode, force this address into 16 bit range to allow
* addressing inside a 64K segment.
*/
- Emit2 (OpCode, ForceWordExpr (Expr));
+ Emit2 (OpCode, ForceWordExpr (Expr));
} else {
Emit2 (OpCode, Expr);
}
/* Description for one instruction */
-typedef struct InsDesc_ InsDesc;
-struct InsDesc_ {
- char Mnemonic [4];
+typedef struct InsDesc InsDesc;
+struct InsDesc {
+ char Mnemonic [4];
unsigned long AddrMode; /* Valid adressing modes */
- unsigned char BaseCode; /* Base opcode */
- unsigned char ExtCode; /* Number of ext code table */
+ unsigned char BaseCode; /* Base opcode */
+ unsigned char ExtCode; /* Number of ext code table */
void (*Emit) (const InsDesc*);/* Handler function */
};
/* An instruction table */
-typedef struct InsTable_ InsTable;
-struct InsTable_ {
- unsigned Count; /* Number of intstructions */
+typedef struct InsTable InsTable;
+struct InsTable {
+ unsigned Count; /* Number of intstructions */
InsDesc Ins[1]; /* Varying length */
};
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/