Skip to content

ARM/Thumb question #27

@rva3

Description

@rva3

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions