Hi, I'm working on ARM/Thumb support for this project. The ARMv7 and Thumb are a bit tricky because they have 3 encodings for the Thumb mode and 2 for ARM. For example, the MOV r0, #0xff can be treated by GAS as:
- MOV r0, #0xff (T1 encoding, ARMv4T+)
- MOV.W r0, #0xff (T2 encoding, ARMv6T2+, if the register is higher than r7 or immediate value is more than u8)
- MOVW r0, #0xff (T3 encoding, ARMv6T2+, if the register is higher than r7 or immediate value is more than 12 bits)
Should the pseudo-instructions be exposed to the end user, i.e.
/// Generate MOV instruction for immediate value
///
/// If `rd` is R8-R15 or the immediate value is bigger than 12 bits then MOVW from T3 is used
///
/// If the immediate value fits into 12 bits or `rd` is R8-R15, T2 encoding is used
///
/// If the immediate value fits into u8 then T1 encoding is used
pub fn mov_imm(&mut self, rd: Register, imm16: u16) -> &mut Self {
self.track_written_register(rd);
let instr = if rd > reg::R7 {
if imm16 > 0x7ff {
encode_thumb_mov_imm_t3(rd, imm16)
} else {
encode_thumb_mov_imm_t2(false, rd, imm16 & 0x7ff)
}
} else {
if imm16 > 0x7ff {
encode_thumb_mov_imm_t3(rd, imm16)
} else if imm16 > u8::MAX as u16 {
encode_thumb_mov_imm_t2(false, rd, imm16 & 0x7ff)
} else {
encode_thumb_mov_imm_t1(rd, (imm16 & 0xff) as u8)
}
};
self.push(instr);
self
}
or the low-level instructions (mov, mov_wide, movw; or mov_t1, movw_t2, movw_t3) instead?
Hi, I'm working on ARM/Thumb support for this project. The ARMv7 and Thumb are a bit tricky because they have 3 encodings for the Thumb mode and 2 for ARM. For example, the MOV r0, #0xff can be treated by GAS as:
Should the pseudo-instructions be exposed to the end user, i.e.
or the low-level instructions (mov, mov_wide, movw; or mov_t1, movw_t2, movw_t3) instead?