diff options
| author | iximeow <me@iximeow.net> | 2021-10-24 19:07:25 -0700 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2021-10-24 19:09:16 -0700 | 
| commit | 8794466963264356d7c271625b9dec85b5edd049 (patch) | |
| tree | a82247231cee09f7586ea1d545a6cb7d11309ec0 /src/armv8 | |
| parent | 405be2ff8dc98560304e4069c11ab754bca05f24 (diff) | |
fix incorrect sign extension for adr and adrp
Diffstat (limited to 'src/armv8')
| -rw-r--r-- | src/armv8/a64.rs | 40 | 
1 files changed, 21 insertions, 19 deletions
diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs index 148b70b..c51d526 100644 --- a/src/armv8/a64.rs +++ b/src/armv8/a64.rs @@ -958,8 +958,8 @@ pub enum Operand {      SIMDRegister(SIMDSizeCode, u16),      RegisterOrSP(SizeCode, u16),      ConditionCode(u8), -    Offset(i32), -    PCOffset(i32), +    Offset(i64), +    PCOffset(i64),      Immediate(u32),      Imm64(u64),      Imm16(u16), @@ -1681,19 +1681,21 @@ impl Decoder<ARMv8> for InstDecoder {                          // PC-rel addressing                          if word >= 0x80000000 {                              inst.opcode = Opcode::ADRP; -                            let imm = ((word >> 3) & 0x1ffffc) | ((word >> 29) & 0x3); +                            let offset = (((word >> 3) & 0x1ffffc) | ((word >> 29) & 0x3)) as i32; +                            let extended_offset = (offset << 11) >> 11;                              inst.operands = [                                  Operand::Register(SizeCode::X, (word & 0x1f) as u16), -                                Operand::Immediate(imm.overflowing_mul(0x1000).0), +                                Operand::Offset((extended_offset as i64) << 12),                                  Operand::Nothing,                                  Operand::Nothing                              ];                          } else {                              inst.opcode = Opcode::ADR; -                            let imm = ((word >> 3) & 0x1ffffc) | ((word >> 29) & 0x3); +                            let offset = (((word >> 3) & 0x1ffffc) | ((word >> 29) & 0x3)) as i32; +                            let extended_offset = (offset << 11) >> 11;                              inst.operands = [                                  Operand::Register(SizeCode::X, (word & 0x1f) as u16), -                                Operand::Immediate(imm), +                                Operand::Offset(extended_offset as i64),                                  Operand::Nothing,                                  Operand::Nothing                              ]; @@ -2213,7 +2215,7 @@ impl Decoder<ARMv8> for InstDecoder {                          inst.operands = [                              Operand::Register(size, Rt), -                            Operand::PCOffset(imm19 << 2), +                            Operand::PCOffset((imm19 << 2) as i64),                              Operand::Nothing,                              Operand::Nothing,                          ]; @@ -2243,7 +2245,7 @@ impl Decoder<ARMv8> for InstDecoder {                          inst.opcode = Opcode::LDR;                          inst.operands = [                              Operand::SIMDRegister(size_code, Rt), -                            Operand::PCOffset(imm19 << 2), +                            Operand::PCOffset((imm19 << 2) as i64),                              Operand::Nothing,                              Operand::Nothing,                          ]; @@ -2992,7 +2994,7 @@ impl Decoder<ARMv8> for InstDecoder {                          let extended_offset = (offset << 4) >> 4;                          inst.opcode = Opcode::B;                          inst.operands = [ -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing,                              Operand::Nothing,                              Operand::Nothing @@ -3005,7 +3007,7 @@ impl Decoder<ARMv8> for InstDecoder {                          let Rt = word & 0x1f;                          inst.operands = [                              Operand::Register(SizeCode::W, Rt as u16), -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing,                              Operand::Nothing                          ]; @@ -3017,7 +3019,7 @@ impl Decoder<ARMv8> for InstDecoder {                          let Rt = word & 0x1f;                          inst.operands = [                              Operand::Register(SizeCode::W, Rt as u16), -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing,                              Operand::Nothing                          ]; @@ -3031,7 +3033,7 @@ impl Decoder<ARMv8> for InstDecoder {                          inst.operands = [                              Operand::Register(SizeCode::W, Rt as u16),                              Operand::Imm16(b as u16), -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing                          ];                      }, @@ -3044,7 +3046,7 @@ impl Decoder<ARMv8> for InstDecoder {                          inst.operands = [                              Operand::Register(SizeCode::W, Rt as u16),                              Operand::Imm16(b as u16), -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing                          ];                      }, @@ -3054,7 +3056,7 @@ impl Decoder<ARMv8> for InstDecoder {                          let cond = word & 0x0f;                          inst.opcode = Opcode::Bcc(cond as u8);                          inst.operands = [ -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing,                              Operand::Nothing,                              Operand::Nothing @@ -3073,7 +3075,7 @@ impl Decoder<ARMv8> for InstDecoder {                          let extended_offset = (offset << 4) >> 4;                          inst.opcode = Opcode::BL;                          inst.operands = [ -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing,                              Operand::Nothing,                              Operand::Nothing @@ -3086,7 +3088,7 @@ impl Decoder<ARMv8> for InstDecoder {                          let Rt = word & 0x1f;                          inst.operands = [                              Operand::Register(SizeCode::X, Rt as u16), -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing,                              Operand::Nothing                          ]; @@ -3098,7 +3100,7 @@ impl Decoder<ARMv8> for InstDecoder {                          let Rt = word & 0x1f;                          inst.operands = [                              Operand::Register(SizeCode::X, Rt as u16), -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing,                              Operand::Nothing                          ]; @@ -3112,7 +3114,7 @@ impl Decoder<ARMv8> for InstDecoder {                          inst.operands = [                              Operand::Register(SizeCode::X, Rt as u16),                              Operand::Imm16((b as u16) | 0x20), -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing                          ];                      }, @@ -3125,7 +3127,7 @@ impl Decoder<ARMv8> for InstDecoder {                          inst.operands = [                              Operand::Register(SizeCode::X, Rt as u16),                              Operand::Imm16((b as u16) | 0x20), -                            Operand::Offset(extended_offset), +                            Operand::Offset(extended_offset as i64),                              Operand::Nothing                          ];                      },  | 
