mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-29 00:11:34 +00:00
Mockout inline asm for riscv
This commit is contained in:
@@ -455,6 +455,10 @@ resolve_relocation_inline :: #force_inline proc(
|
||||
return true
|
||||
}
|
||||
|
||||
is_implicit_op_inline :: #force_inline proc "contextless" (op: Operand_Type) -> bool {
|
||||
return op == .GPR_SP
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Scatter / gather helpers for B-type and J-type immediates
|
||||
// =============================================================================
|
||||
|
||||
@@ -52,11 +52,12 @@ Feature :: enum u8 {
|
||||
}
|
||||
|
||||
Encoding_Flags :: bit_field u8 {
|
||||
rv32_only: bool | 1, // RV32 base only
|
||||
rv64_only: bool | 1, // RV64 base only (e.g. LD/SD/ADDIW/...)
|
||||
branch: bool | 1, // changes PC
|
||||
fp_round: bool | 1, // funct3 doubles as FP rounding-mode field
|
||||
_: u8 | 4,
|
||||
rv32_only: bool | 1, // RV32 base only
|
||||
rv64_only: bool | 1, // RV64 base only (e.g. LD/SD/ADDIW/...)
|
||||
branch: bool | 1, // changes PC
|
||||
fp_round: bool | 1, // funct3 doubles as FP rounding-mode field
|
||||
explicit_count: u8 | 3,
|
||||
has_implicit: bool | 1,
|
||||
}
|
||||
|
||||
// What the user passes in.
|
||||
@@ -149,7 +150,7 @@ Encoding :: struct #packed {
|
||||
enc: [4]Operand_Encoding, // 4
|
||||
bits: u32, // 4 -- static bit pattern
|
||||
mask: u32, // 4 -- which bits are static
|
||||
feature: Feature, // 1
|
||||
feature: Feature, // 1
|
||||
flags: Encoding_Flags, // 1
|
||||
}
|
||||
#assert(size_of(Encoding) == 20)
|
||||
|
||||
@@ -113,7 +113,22 @@ emit_encode_tables :: proc() -> (total: int) {
|
||||
fmt.sbprintfln(&sb, "\t// .%v", m)
|
||||
for &form in forms {
|
||||
f := &form.encoding
|
||||
write_row(&sb, f.mnemonic, f.ops, f.enc, f.bits, f.mask, f.feature, f.flags)
|
||||
flags := f.flags
|
||||
|
||||
encoding_operand_count: u8 = 0
|
||||
has_implicit := false
|
||||
for op_type in f.ops {
|
||||
if op_type == .NONE { break }
|
||||
if lib.is_implicit_op_inline(op_type) {
|
||||
has_implicit = true
|
||||
} else {
|
||||
encoding_operand_count += 1
|
||||
}
|
||||
}
|
||||
flags.explicit_count = encoding_operand_count
|
||||
flags.has_implicit = has_implicit
|
||||
|
||||
write_row(&sb, f.mnemonic, f.ops, f.enc, f.bits, f.mask, f.feature, flags)
|
||||
}
|
||||
}
|
||||
strings.write_string(&sb, "}\n\n")
|
||||
|
||||
@@ -309,6 +309,20 @@ main :: proc() {
|
||||
// NOTE: SideEffectFlag_HINT deliberately excluded — inert, may be DCE'd.
|
||||
return ((side_effects & VOLATILE_SE) != 0);
|
||||
}
|
||||
|
||||
u8 is_call_or_mem() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_CONTROL) != 0 ||
|
||||
(cast(u16)implicit_wr & ClobberReg_RSP) != 0;
|
||||
}
|
||||
bool has_control() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_CONTROL) != 0;
|
||||
}
|
||||
bool has_halt() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_HALT) != 0;
|
||||
}
|
||||
bool is_conditional() const {
|
||||
return has_control() && (cast(u16)flags_rd != 0);
|
||||
}
|
||||
};
|
||||
|
||||
void clobber_implicit_regs(StringSet *clobber_registers_set, u16 implicit_regs) {
|
||||
@@ -381,13 +395,6 @@ main :: proc() {
|
||||
fmt.sbprintf(&sb, "return cast(u8)((flags>>%du)&((1u<<%d)-1));", bit_offset, bit_size)
|
||||
strings.write_string(&sb, " }\n")
|
||||
}
|
||||
{
|
||||
bit_offset := intrinsics.type_field_bit_offset(Encoding_Flags, "op_count")
|
||||
bit_size := intrinsics.type_field_bit_size(Encoding_Flags, "op_count")
|
||||
strings.write_string(&sb, "\t\tu8 op_count () const { ")
|
||||
fmt.sbprintf(&sb, "return cast(u8)((flags>>%du)&((1u<<%d)-1));", bit_offset, bit_size)
|
||||
strings.write_string(&sb, " }\n")
|
||||
}
|
||||
{
|
||||
bit_offset := intrinsics.type_field_bit_offset(Encoding_Flags, "lock_ok")
|
||||
strings.write_string(&sb, "\t\tbool lock_ok () const { ")
|
||||
@@ -421,7 +428,8 @@ main :: proc() {
|
||||
|
||||
strings.write_string(&sb, """
|
||||
|
||||
bool init() {
|
||||
bool init(i64 word_size) {
|
||||
gb_unused(word_size);
|
||||
string_map_init(&mnemonic_map, MNEMONIC_COUNT*2);
|
||||
for (u16 m = M_INVALID+1; m < MNEMONIC_COUNT; m++) {
|
||||
string_map_set(&mnemonic_map, mnemonic_strings[m], cast(Mnemonic)m);
|
||||
|
||||
Reference in New Issue
Block a user