mirror of
https://github.com/gbdev/rgbds.git
synced 2026-09-16 02:37:06 +00:00
Warn about signed 8-bit truncation for add sp, e8 and ld hl, sp + e8
This commit is contained in:
@@ -57,10 +57,12 @@ struct Expression {
|
|||||||
void addCheckBitIndex(uint8_t mask);
|
void addCheckBitIndex(uint8_t mask);
|
||||||
|
|
||||||
void checkNBit(uint8_t n) const;
|
void checkNBit(uint8_t n) const;
|
||||||
|
void checkSignedNBit(uint8_t n) const;
|
||||||
|
|
||||||
void encode(std::vector<uint8_t> &buffer) const;
|
void encode(std::vector<uint8_t> &buffer) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool checkNBit(int32_t v, uint8_t n, char const *name);
|
bool checkNBit(int32_t v, uint8_t n, char const *name);
|
||||||
|
bool checkSignedNBit(int32_t v, uint8_t n, char const *name);
|
||||||
|
|
||||||
#endif // RGBDS_ASM_RPN_HPP
|
#endif // RGBDS_ASM_RPN_HPP
|
||||||
|
|||||||
+11
-3
@@ -340,6 +340,7 @@
|
|||||||
%type <Expression> reloc_3bit
|
%type <Expression> reloc_3bit
|
||||||
%type <Expression> reloc_8bit
|
%type <Expression> reloc_8bit
|
||||||
%type <Expression> reloc_16bit
|
%type <Expression> reloc_16bit
|
||||||
|
%type <Expression> reloc_8bit_signed
|
||||||
|
|
||||||
// Constant numbers
|
// Constant numbers
|
||||||
%type <int32_t> iconst
|
%type <int32_t> iconst
|
||||||
@@ -1241,6 +1242,13 @@ reloc_8bit:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
reloc_8bit_signed:
|
||||||
|
relocexpr {
|
||||||
|
$$ = std::move($1);
|
||||||
|
$$.checkSignedNBit(8);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
reloc_16bit:
|
reloc_16bit:
|
||||||
relocexpr {
|
relocexpr {
|
||||||
$$ = std::move($1);
|
$$ = std::move($1);
|
||||||
@@ -1886,7 +1894,7 @@ sm83_add:
|
|||||||
| SM83_ADD MODE_HL COMMA reg_ss {
|
| SM83_ADD MODE_HL COMMA reg_ss {
|
||||||
sect_ConstByte(0x09 | ($4 << 4));
|
sect_ConstByte(0x09 | ($4 << 4));
|
||||||
}
|
}
|
||||||
| SM83_ADD MODE_SP COMMA reloc_8bit {
|
| SM83_ADD MODE_SP COMMA reloc_8bit_signed {
|
||||||
sect_ConstByte(0xE8);
|
sect_ConstByte(0xE8);
|
||||||
sect_RelByte($4, 1);
|
sect_RelByte($4, 1);
|
||||||
}
|
}
|
||||||
@@ -2434,11 +2442,11 @@ op_a_n:
|
|||||||
op_sp_offset:
|
op_sp_offset:
|
||||||
OP_ADD relocexpr {
|
OP_ADD relocexpr {
|
||||||
$$ = std::move($2);
|
$$ = std::move($2);
|
||||||
$$.checkNBit(8);
|
$$.checkSignedNBit(8);
|
||||||
}
|
}
|
||||||
| OP_SUB relocexpr {
|
| OP_SUB relocexpr {
|
||||||
$$.makeUnaryOp(RPN_NEG, std::move($2));
|
$$.makeUnaryOp(RPN_NEG, std::move($2));
|
||||||
$$.checkNBit(8);
|
$$.checkSignedNBit(8);
|
||||||
}
|
}
|
||||||
| %empty {
|
| %empty {
|
||||||
::error("\"LD HL, SP\" is not a valid instruction; use \"LD HL, SP + 0\"");
|
::error("\"LD HL, SP\" is not a valid instruction; use \"LD HL, SP + 0\"");
|
||||||
|
|||||||
@@ -512,6 +512,25 @@ bool checkNBit(int32_t v, uint8_t n, char const *name) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks that an RPN expression's value fits within N bits (must be signed)
|
||||||
|
void Expression::checkSignedNBit(uint8_t n) const {
|
||||||
|
if (isKnown()) {
|
||||||
|
::checkSignedNBit(value(), n, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkSignedNBit(int32_t v, uint8_t n, char const *name) {
|
||||||
|
assume(n != 0); // That doesn't make sense
|
||||||
|
assume(n < CHAR_BIT * sizeof(int) - 1); // Otherwise `1 << n` is UB
|
||||||
|
|
||||||
|
if (v < -(1 << (n - 1)) || v >= 1 << (n - 1)) {
|
||||||
|
warning(WARNING_TRUNCATION_1, "%s must be signed %u-bit", name ? name : "Expression", n);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Expression::encode(std::vector<uint8_t> &buffer) const {
|
void Expression::encode(std::vector<uint8_t> &buffer) const {
|
||||||
assume(buffer.empty());
|
assume(buffer.empty());
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
section "test", rom0
|
||||||
|
|
||||||
|
opt Wtruncation=1
|
||||||
|
|
||||||
|
; good
|
||||||
|
ld hl, sp + 0
|
||||||
|
ld hl, sp + 127
|
||||||
|
ld hl, sp - 128
|
||||||
|
ld hl, sp + -128
|
||||||
|
add sp, 0
|
||||||
|
add sp, 127
|
||||||
|
add sp, -128
|
||||||
|
|
||||||
|
; bad
|
||||||
|
ld hl, sp + 128
|
||||||
|
ld hl, sp - 129
|
||||||
|
ld hl, sp + 255
|
||||||
|
ld hl, sp - 256
|
||||||
|
add sp, 128
|
||||||
|
add sp, -129
|
||||||
|
add sp, 255
|
||||||
|
add sp, -256
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
warning: Expression must be signed 8-bit [-Wtruncation]
|
||||||
|
at sp-signed-truncation.asm(15)
|
||||||
|
warning: Expression must be signed 8-bit [-Wtruncation]
|
||||||
|
at sp-signed-truncation.asm(16)
|
||||||
|
warning: Expression must be signed 8-bit [-Wtruncation]
|
||||||
|
at sp-signed-truncation.asm(17)
|
||||||
|
warning: Expression must be signed 8-bit [-Wtruncation]
|
||||||
|
at sp-signed-truncation.asm(18)
|
||||||
|
warning: Expression must be signed 8-bit [-Wtruncation]
|
||||||
|
at sp-signed-truncation.asm(19)
|
||||||
|
warning: Expression must be signed 8-bit [-Wtruncation]
|
||||||
|
at sp-signed-truncation.asm(20)
|
||||||
|
warning: Expression must be signed 8-bit [-Wtruncation]
|
||||||
|
at sp-signed-truncation.asm(21)
|
||||||
|
warning: Expression must be signed 8-bit [-Wtruncation]
|
||||||
|
at sp-signed-truncation.asm(22)
|
||||||
Reference in New Issue
Block a user