pub const REG_FOURTH_ARG: &str = "rcx";
pub const REG_C: &str = "rdx";
pub const REG_C_W: &str = "edx";
pub const REG_C_B: &str = "dx";
pub const REG_C_LB: &str = "dl";
pub const REG_THIRD_ARG: &str = "rdx";
pub const REG_B: &str = "rsi";
pub const REG_B_W: &str = "esi";
pub const REG_SECOND_ARG: &str = "rsi";
pub const REG_A: &str = "rdi";
pub const REG_A_W: &str = "edi";
pub const REG_FIRST_ARG: &str = "rdi";
pub const REG_RETURN_VAL: &str = "rax";
pub const REG_D: &str = "rax";
pub const REG_D_W: &str = "eax";
pub const REG_INSTRET_END: &str = "r12";
pub const REG_EXEC_STATE_PTR: &str = "rbx";
pub const REG_TRACE_HEIGHT: &str = "r14";
pub const REG_AS2_PTR: &str = "r15";
pub const DEFAULT_PC_OFFSET: i32 = 4;
pub const RISCV_TO_X86_OVERRIDE_MAP: [Option<&str>; 32] = [
None, None, None, None, None, None, None, None, None, None, Some("r10d"), Some("r11d"), Some("r9d"), Some("r8d"), Some("ebp"), Some("r13d"), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, ];
pub fn sync_xmm_to_gpr() -> String {
let mut asm_str = String::new();
for (rv32_reg, override_reg_opt) in RISCV_TO_X86_OVERRIDE_MAP.iter().copied().enumerate() {
if let Some(override_reg) = override_reg_opt {
let xmm_reg = rv32_reg / 2;
let lane = rv32_reg % 2;
asm_str += &format!(" pextrd {override_reg}, xmm{xmm_reg}, {lane}\n");
}
}
asm_str
}
pub fn sync_gpr_to_xmm() -> String {
let mut asm_str = String::new();
for (rv32_reg, override_reg_opt) in RISCV_TO_X86_OVERRIDE_MAP.iter().copied().enumerate() {
if let Some(override_reg) = override_reg_opt {
let xmm_reg = rv32_reg / 2;
let lane = rv32_reg % 2;
asm_str += &format!(" pinsrd xmm{xmm_reg}, {override_reg}, {lane}\n");
}
}
asm_str
}
#[derive(Copy, Clone)]
pub enum Width {
W64,
W32,
W16,
W8L,
W8H,
}
pub fn convert_x86_reg(any: &str, to: Width) -> Option<&'static str> {
#[rustfmt::skip]
const T: [(&str,&str,&str,&str,Option<&str>); 16] = [
("rax","eax","ax","al",Some("ah")), ("rbx","ebx","bx","bl",Some("bh")),
("rcx","ecx","cx","cl",Some("ch")), ("rdx","edx","dx","dl",Some("dh")),
("rsi","esi","si","sil",None), ("rdi","edi","di","dil",None),
("rbp","ebp","bp","bpl",None), ("rsp","esp","sp","spl",None),
("r8","r8d","r8w","r8b",None), ("r9","r9d","r9w","r9b",None),
("r10","r10d","r10w","r10b",None), ("r11","r11d","r11w","r11b",None),
("r12","r12d","r12w","r12b",None), ("r13","r13d","r13w","r13b",None),
("r14","r14d","r14w","r14b",None), ("r15","r15d","r15w","r15b",None),
];
fn pick(
row: (
&'static str,
&'static str,
&'static str,
&'static str,
Option<&'static str>,
),
w: Width,
) -> Option<&'static str> {
match w {
Width::W64 => Some(row.0),
Width::W32 => Some(row.1),
Width::W16 => Some(row.2),
Width::W8L => Some(row.3),
Width::W8H => row.4,
}
}
let key = any.to_ascii_lowercase();
for row in T {
if [row.0, row.1, row.2, row.3].iter().any(|&n| n == key) || row.4 == Some(key.as_str()) {
return pick(row, to);
}
}
None
}