Skip to content

Commit a3f4053

Browse files
committed
Fix immediate offset scaling for Thumb LDRB/LDRH/STRB/STRH
1 parent 583e670 commit a3f4053

File tree

5 files changed

+57
-27
lines changed

5 files changed

+57
-27
lines changed

disasm/src/thumb/generated.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,14 +1743,30 @@ impl Ins {
17431743
pub fn field_low_blx_offset_11(&self) -> u32 {
17441744
(self.code & 0x000007ff) << 1 & !3
17451745
}
1746-
/// offset_5: 7-bit immediate offset
1746+
/// word_offset_5: 7-bit immediate offset
17471747
#[inline(always)]
1748-
pub fn field_offset_5(&self) -> OffsetImm {
1748+
pub fn field_word_offset_5(&self) -> OffsetImm {
17491749
OffsetImm {
17501750
post_indexed: false,
17511751
value: (((self.code >> 6) & 0x0000001f) << 2) as i32,
17521752
}
17531753
}
1754+
/// halfword_offset_5: 6-bit immediate offset
1755+
#[inline(always)]
1756+
pub fn field_halfword_offset_5(&self) -> OffsetImm {
1757+
OffsetImm {
1758+
post_indexed: false,
1759+
value: (((self.code >> 6) & 0x0000001f) << 1) as i32,
1760+
}
1761+
}
1762+
/// byte_offset_5: 5-bit immediate offset
1763+
#[inline(always)]
1764+
pub fn field_byte_offset_5(&self) -> OffsetImm {
1765+
OffsetImm {
1766+
post_indexed: false,
1767+
value: (((self.code >> 6) & 0x0000001f)) as i32,
1768+
}
1769+
}
17541770
/// cpsr_flags: CPSR flags
17551771
#[inline(always)]
17561772
pub fn field_cpsr_flags(&self) -> CpsrFlags {
@@ -2726,7 +2742,7 @@ fn parse_ldr_i(out: &mut ParsedIns, ins: Ins, flags: &ParseFlags) {
27262742
args: [
27272743
Argument::Reg(ins.field_rd_0()),
27282744
Argument::Reg(ins.field_rn_3_deref()),
2729-
Argument::OffsetImm(ins.field_offset_5()),
2745+
Argument::OffsetImm(ins.field_word_offset_5()),
27302746
Argument::None,
27312747
Argument::None,
27322748
Argument::None,
@@ -2778,7 +2794,7 @@ fn parse_ldrb_i(out: &mut ParsedIns, ins: Ins, flags: &ParseFlags) {
27782794
args: [
27792795
Argument::Reg(ins.field_rd_0()),
27802796
Argument::Reg(ins.field_rn_3_deref()),
2781-
Argument::OffsetImm(ins.field_offset_5()),
2797+
Argument::OffsetImm(ins.field_byte_offset_5()),
27822798
Argument::None,
27832799
Argument::None,
27842800
Argument::None,
@@ -2804,7 +2820,7 @@ fn parse_ldrh_i(out: &mut ParsedIns, ins: Ins, flags: &ParseFlags) {
28042820
args: [
28052821
Argument::Reg(ins.field_rd_0()),
28062822
Argument::Reg(ins.field_rn_3_deref()),
2807-
Argument::OffsetImm(ins.field_offset_5()),
2823+
Argument::OffsetImm(ins.field_halfword_offset_5()),
28082824
Argument::None,
28092825
Argument::None,
28102826
Argument::None,
@@ -3310,7 +3326,7 @@ fn parse_str_i(out: &mut ParsedIns, ins: Ins, flags: &ParseFlags) {
33103326
args: [
33113327
Argument::Reg(ins.field_rd_0()),
33123328
Argument::Reg(ins.field_rn_3_deref()),
3313-
Argument::OffsetImm(ins.field_offset_5()),
3329+
Argument::OffsetImm(ins.field_word_offset_5()),
33143330
Argument::None,
33153331
Argument::None,
33163332
Argument::None,
@@ -3349,7 +3365,7 @@ fn parse_strb_i(out: &mut ParsedIns, ins: Ins, flags: &ParseFlags) {
33493365
args: [
33503366
Argument::Reg(ins.field_rd_0()),
33513367
Argument::Reg(ins.field_rn_3_deref()),
3352-
Argument::OffsetImm(ins.field_offset_5()),
3368+
Argument::OffsetImm(ins.field_byte_offset_5()),
33533369
Argument::None,
33543370
Argument::None,
33553371
Argument::None,
@@ -3375,7 +3391,7 @@ fn parse_strh_i(out: &mut ParsedIns, ins: Ins, flags: &ParseFlags) {
33753391
args: [
33763392
Argument::Reg(ins.field_rd_0()),
33773393
Argument::Reg(ins.field_rn_3_deref()),
3378-
Argument::OffsetImm(ins.field_offset_5()),
3394+
Argument::OffsetImm(ins.field_halfword_offset_5()),
33793395
Argument::None,
33803396
Argument::None,
33813397
Argument::None,

disasm/tests/test_thumb_v4t.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,13 @@ mod tests {
117117

118118
#[test]
119119
fn test_ldrb() {
120-
assert_asm!(0x7c22, "ldrb r2, [r4, #0x40]");
120+
assert_asm!(0x7c22, "ldrb r2, [r4, #0x10]");
121121
assert_asm!(0x5c22, "ldrb r2, [r4, r0]");
122122
}
123123

124124
#[test]
125125
fn test_ldrh() {
126-
assert_asm!(0x8c22, "ldrh r2, [r4, #0x40]");
126+
assert_asm!(0x8c22, "ldrh r2, [r4, #0x20]");
127127
assert_asm!(0x5a22, "ldrh r2, [r4, r0]");
128128
}
129129

@@ -210,13 +210,13 @@ mod tests {
210210

211211
#[test]
212212
fn test_strb() {
213-
assert_asm!(0x7422, "strb r2, [r4, #0x40]");
213+
assert_asm!(0x7422, "strb r2, [r4, #0x10]");
214214
assert_asm!(0x5422, "strb r2, [r4, r0]");
215215
}
216216

217217
#[test]
218218
fn test_strh() {
219-
assert_asm!(0x8422, "strh r2, [r4, #0x40]");
219+
assert_asm!(0x8422, "strh r2, [r4, #0x20]");
220220
assert_asm!(0x5222, "strh r2, [r4, r0]");
221221
}
222222

disasm/tests/test_thumb_v5te.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,13 @@ mod tests {
131131

132132
#[test]
133133
fn test_ldrb() {
134-
assert_asm!(0x7c22, "ldrb r2, [r4, #0x40]");
134+
assert_asm!(0x7c22, "ldrb r2, [r4, #0x10]");
135135
assert_asm!(0x5c22, "ldrb r2, [r4, r0]");
136136
}
137137

138138
#[test]
139139
fn test_ldrh() {
140-
assert_asm!(0x8c22, "ldrh r2, [r4, #0x40]");
140+
assert_asm!(0x8c22, "ldrh r2, [r4, #0x20]");
141141
assert_asm!(0x5a22, "ldrh r2, [r4, r0]");
142142
}
143143

@@ -224,13 +224,13 @@ mod tests {
224224

225225
#[test]
226226
fn test_strb() {
227-
assert_asm!(0x7422, "strb r2, [r4, #0x40]");
227+
assert_asm!(0x7422, "strb r2, [r4, #0x10]");
228228
assert_asm!(0x5422, "strb r2, [r4, r0]");
229229
}
230230

231231
#[test]
232232
fn test_strh() {
233-
assert_asm!(0x8422, "strh r2, [r4, #0x40]");
233+
assert_asm!(0x8422, "strh r2, [r4, #0x20]");
234234
assert_asm!(0x5222, "strh r2, [r4, r0]");
235235
}
236236

disasm/tests/test_thumb_v6k.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,13 @@ mod tests {
136136

137137
#[test]
138138
fn test_ldrb() {
139-
assert_asm!(0x7c22, "ldrb r2, [r4, #0x40]");
139+
assert_asm!(0x7c22, "ldrb r2, [r4, #0x10]");
140140
assert_asm!(0x5c22, "ldrb r2, [r4, r0]");
141141
}
142142

143143
#[test]
144144
fn test_ldrh() {
145-
assert_asm!(0x8c22, "ldrh r2, [r4, #0x40]");
145+
assert_asm!(0x8c22, "ldrh r2, [r4, #0x20]");
146146
assert_asm!(0x5a22, "ldrh r2, [r4, r0]");
147147
}
148148

@@ -250,13 +250,13 @@ mod tests {
250250

251251
#[test]
252252
fn test_strb() {
253-
assert_asm!(0x7422, "strb r2, [r4, #0x40]");
253+
assert_asm!(0x7422, "strb r2, [r4, #0x10]");
254254
assert_asm!(0x5422, "strb r2, [r4, r0]");
255255
}
256256

257257
#[test]
258258
fn test_strh() {
259-
assert_asm!(0x8422, "strh r2, [r4, #0x40]");
259+
assert_asm!(0x8422, "strh r2, [r4, #0x20]");
260260
assert_asm!(0x5222, "strh r2, [r4, r0]");
261261
}
262262

specs/thumb.yaml

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,27 @@ fields:
276276
desc: 23-bit signed BLX target offset (low part)
277277
value: !Expr self.code.bits(0,11) << 1 & !3
278278

279-
- name: offset_5
279+
- name: word_offset_5
280280
arg: offset_imm
281281
desc: 7-bit immediate offset
282282
value: !Struct
283283
value: !Expr self.code.bits(6,11) << 2
284284
post_indexed: !Bool false
285285

286+
- name: halfword_offset_5
287+
arg: offset_imm
288+
desc: 6-bit immediate offset
289+
value: !Struct
290+
value: !Expr self.code.bits(6,11) << 1
291+
post_indexed: !Bool false
292+
293+
- name: byte_offset_5
294+
arg: offset_imm
295+
desc: 5-bit immediate offset
296+
value: !Struct
297+
value: !Expr self.code.bits(6,11)
298+
post_indexed: !Bool false
299+
286300
- name: cpsr_flags
287301
arg: cpsr_flags
288302
desc: CPSR flags
@@ -659,7 +673,7 @@ opcodes:
659673
desc: Load Register with immediate offset
660674
bitmask: 0xf800
661675
pattern: 0x6800
662-
args: [Rd_0, Rn_3_deref, offset_5]
676+
args: [Rd_0, Rn_3_deref, word_offset_5]
663677
defs: [Rd_0]
664678
uses: [Rn_3_deref]
665679

@@ -691,7 +705,7 @@ opcodes:
691705
desc: Load Register Byte with immediate offset
692706
bitmask: 0xf800
693707
pattern: 0x7800
694-
args: [Rd_0, Rn_3_deref, offset_5]
708+
args: [Rd_0, Rn_3_deref, byte_offset_5]
695709
defs: [Rd_0]
696710
uses: [Rn_3_deref]
697711

@@ -707,7 +721,7 @@ opcodes:
707721
desc: Load Register Halfword with immediate offset
708722
bitmask: 0xf800
709723
pattern: 0x8800
710-
args: [Rd_0, Rn_3_deref, offset_5]
724+
args: [Rd_0, Rn_3_deref, halfword_offset_5]
711725
defs: [Rd_0]
712726
uses: [Rn_3_deref]
713727

@@ -947,7 +961,7 @@ opcodes:
947961
desc: Store Register with immediate offset
948962
bitmask: 0xf800
949963
pattern: 0x6000
950-
args: [Rd_0, Rn_3_deref, offset_5]
964+
args: [Rd_0, Rn_3_deref, word_offset_5]
951965
defs: [Rn_3_deref]
952966
uses: [Rd_0]
953967

@@ -971,7 +985,7 @@ opcodes:
971985
desc: Store Register Byte with immediate offset
972986
bitmask: 0xf800
973987
pattern: 0x7000
974-
args: [Rd_0, Rn_3_deref, offset_5]
988+
args: [Rd_0, Rn_3_deref, byte_offset_5]
975989
defs: [Rn_3_deref]
976990
uses: [Rd_0]
977991

@@ -987,7 +1001,7 @@ opcodes:
9871001
desc: Store Register Halfword with immediate offset
9881002
bitmask: 0xf800
9891003
pattern: 0x8000
990-
args: [Rd_0, Rn_3_deref, offset_5]
1004+
args: [Rd_0, Rn_3_deref, halfword_offset_5]
9911005
defs: [Rn_3_deref]
9921006
uses: [Rd_0]
9931007

0 commit comments

Comments
 (0)