Skip to content

Commit 43b0dcf

Browse files
bmourad01bmourad01
andauthored
Adds more missing Thumb instructions (#1511)
* Adds more missing instructions * `ADR` uses PC aligned by 4 * Fixes `UXT/SXT` bug in the Core Theory Thumb lifter Co-authored-by: bmourad01 <bmourad@draper.com>
1 parent 5730f5c commit 43b0dcf

File tree

5 files changed

+106
-11
lines changed

5 files changed

+106
-11
lines changed

plugins/arm/semantics/arm-bits.lisp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,16 @@
9595
(let ((bitv-length (word-width bitv)))
9696
(assert-msg (= 0 (mod n bitv-length)) "replicate-to-fill n not multiple of len(bitv)")
9797
(replicate bitv (/ n bitv-length))))
98+
99+
(defun i-shift (r simm)
100+
"(i-shift r simm) shifts r according to the encoded shift simm.
101+
The first three bits of simm indicate the shift type, and the
102+
remaining bits indicate the shift amount."
103+
(let ((amt (rshift simm 3)))
104+
(case (extract 2 0 simm)
105+
0b000 r ; none
106+
0b001 (arshift r amt) ; asr
107+
0b010 (lshift r amt) ; lsl
108+
0b011 (rshift r amt) ; lsr
109+
0b100 (logor (rshift r amt) (lshift r (- 32 amt))) ; ror
110+
0b101 (logor (lshift (cast-unsigned 32 CF) 31) (rshift r 1))))) ; rrx

plugins/arm/semantics/thumb.lisp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@
1111

1212
(in-package thumb)
1313

14+
(defun tCMPhir (rn rm cnd _)
15+
"cmp rn, rn"
16+
(when (condition-holds cnd)
17+
(let ((r (- rn rm)))
18+
(set-nzcv-from-registers r rn rm))))
19+
20+
(defun tADR (rd lbl cnd _)
21+
"adr rd, lbl"
22+
(when (condition-holds cnd)
23+
(let ((pc (* 4 (/ (t2pc) 4))))
24+
(set$ rd (+ pc (lshift lbl 2))))))
25+
1426
(defmacro tLOGs (op rd rn rm cnd)
1527
(prog (set$ rd (op rn rm))
1628
(when (is-unconditional cnd)
@@ -20,6 +32,11 @@
2032
(defun tEOR (rd _ rn rm cnd _)
2133
(tLOGs logxor rd rn rm cnd))
2234

35+
(defun t2EORrs (rd rn rm simm cnd _ _)
36+
"eor.w rd, rn, rm, simm"
37+
(when (condition-holds cnd)
38+
(set$ rd (logxor rn (i-shift rm simm)))))
39+
2340
(defun tAND (rd _ rn rm cnd _)
2441
(tLOGs logand rd rn rm cnd))
2542

@@ -41,14 +58,33 @@
4158
(extract 23 16 rn)
4259
(extract 31 24 rn)))))
4360

61+
(defun tREV16 (rd rm cnd _)
62+
"rev16 rd rm"
63+
(when (condition-holds cnd)
64+
(set$ rd (concat
65+
(extract 23 16 rm)
66+
(extract 31 24 rm)
67+
(extract 7 0 rm)
68+
(extract 15 8 rm)))))
69+
4470
(defun tLSLrr (rd _ rn rm cnd _)
4571
"lsls rd, rn, rm"
4672
(shift-with-carry lshift rd rn rm cnd))
4773

74+
(defun t2LSLri (rd rm imm cnd _ _)
75+
"lsl.w rd, rm, #imm"
76+
(when (condition-holds cnd)
77+
(set$ rd (lshift rm imm))))
78+
4879
(defun tLSRrr (rd _ rn rm cnd _)
4980
"lsrs rd, rn, rm"
5081
(shift-with-carry rshift rd rn rm cnd))
5182

83+
(defun t2LSRri (rd rm imm cnd _ _)
84+
"lsr.w rd, rm, #imm"
85+
(when (condition-holds cnd)
86+
(set$ rd (rshift rm imm))))
87+
5288
(defun tTST (rn rm _ _)
5389
"tst rn, rm"
5490
(let ((rd (logand rn rm)))
@@ -59,26 +95,47 @@
5995
(when (condition-holds cnd)
6096
(set$ rd (+ rn (t2reg rm)))))
6197

98+
(defun t2ADDrs (rd rn rm simm cnd _ _)
99+
"add.w rd, rn, rm, simm"
100+
(when (condition-holds cnd)
101+
(set$ rd (+ rn (i-shift rn simm)))))
102+
62103
(defun tSBC (rd _ rn rm cnd _)
63104
(add-with-carry/it-block rd rn (lnot rm) CF cnd))
64105

65106
(defun tRSB (rd _ rn cnd _)
66107
"rsbs r3, r2, #0"
67108
(add-with-carry/it-block rd 0 (lnot rn) 1 cnd))
68109

110+
(defun t2RSBrs (rd rn rm simm cnd _ _)
111+
"rsb rd, rn, rm, simm"
112+
(when (condition-holds cnd)
113+
(set$ rd (- (i-shift rm simm) rn))))
114+
69115
(defun tMUL (rd _ rn rm cnd _)
70116
(when (condition-holds cnd)
71117
(set$ rd (* rn rm))
72118
(when (is-unconditional cnd)
73119
(set ZF (is-zero rd))
74120
(set NF (msb rd)))))
75121

122+
(defun t2STR_PRE (_ rt rn off cnd _)
123+
"str rt [rn, #off]!"
124+
(when (condition-holds cnd)
125+
(set$ rn (+ rn off))
126+
(store-word rn rt)))
127+
76128
(defun t2STRDi8 (rt1 rt2 rn imm pre _)
77129
"strd rt1, rt2, [rn, off]"
78130
(when (condition-holds pre)
79131
(store-word (+ rn imm) rt1)
80132
(store-word (+ rn imm (sizeof word-width)) rt2)))
81133

134+
(defun t2STRs (rt rn rm imm cnd _)
135+
"str.w rt [rn, rm, lsl imm]"
136+
(when (condition-holds cnd)
137+
(store-word (+ rn (lshift rm imm)) rt)))
138+
82139
(defun t2ADDri12 (rd rn imm pre _)
83140
"addw rd, rn, imm; A7-189, T4 "
84141
(when (condition-holds pre)
@@ -115,6 +172,30 @@
115172
(when (condition-holds pre)
116173
(t2set rt (load-word (+ rn (lshift rm imm))))))
117174

175+
(defun t2LDRi8 (rt rn imm cnd _)
176+
"ldr rt, [rn, #-imm]"
177+
(when (condition-holds cnd)
178+
(set$ rt (load-word (+ rn imm)))))
179+
180+
(defun t2LDRDi8 (rt rt2 rn imm cnd _)
181+
"ldrd rt, rt2, [rn, #imm]"
182+
(when (condition-holds cnd)
183+
(set$ rt (load-word (+ rn imm)))
184+
(set$ rt2 (load-word (+ rn imm 4)))))
185+
186+
(defun t2LDR_POST (rt _ rn off cnd _)
187+
"ldr rt, [rn], #imm"
188+
(when (condition-holds cnd)
189+
(let ((tmp rn))
190+
(set$ rn (+ rn off))
191+
(t2set rt (load-word tmp)))))
192+
193+
(defun t2LDRB_PRE (rt _ rn off cnd _)
194+
"ldrb rt, [rn, #off]!"
195+
(when (condition-holds cnd)
196+
(set$ rn (+ rn off))
197+
(set$ rt (cast-unsigned 32 (load-bits 8 rn)))))
198+
118199
(defun t2LDRSBi12 (rt rn imm pre _)
119200
"ldrsb.w rt, [rn, imm]"
120201
(when (condition-holds pre)

plugins/thumb/thumb_bits.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ module Make(CT : Theory.Core) = struct
77
open Thumb_core.Make(CT)
88
open Syntax
99

10-
let sx rd rm =
11-
rd <-? CT.signed s32 (var rm)
10+
let sx s rd rm =
11+
rd <-? CT.signed s32 (CT.low s (var rm))
1212

13-
let ux rd rm =
14-
rd <-? CT.unsigned s32 (var rm)
13+
let ux s rd rm =
14+
rd <-? CT.unsigned s32 (CT.low s (var rm))
1515
end

plugins/thumb/thumb_bits.mli

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ open Bap_core_theory
22
open Thumb_core
33
open Thumb_opcodes
44

5-
module Make(CT : Theory.Core) : sig
5+
module Make(_ : Theory.Core) : sig
66
open Theory
7-
val sx : r32 reg -> _ reg -> cond -> unit eff
8-
val ux : r32 reg -> _ reg -> cond -> unit eff
7+
val sx : 'a Bitv.t Value.sort -> r32 reg -> _ reg -> cond -> unit eff
8+
val ux : 'a Bitv.t Value.sort -> r32 reg -> _ reg -> cond -> unit eff
99
end

plugins/thumb/thumb_main.ml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,12 @@ module Thumb(CT : Theory.Core) = struct
174174

175175
let lift_bits opcode insn =
176176
let open Thumb_bits.Make(CT) in
177+
let open Thumb_core in
177178
match opcode, (MC.Insn.ops insn : Op.t array) with
178-
| `tSXTB, [|Reg rd; Reg rm; Imm c; _|] -> sx (reg rd) (reg rm) (cnd c)
179-
| `tSXTH, [|Reg rd; Reg rm; Imm c; _|] -> sx (reg rd) (reg rm) (cnd c)
180-
| `tUXTB, [|Reg rd; Reg rm; Imm c; _|] -> ux (reg rd) (reg rm) (cnd c)
181-
| `tUXTH, [|Reg rd; Reg rm; Imm c; _|] -> ux (reg rd) (reg rm) (cnd c)
179+
| `tSXTB, [|Reg rd; Reg rm; Imm c; _|] -> sx s8 (reg rd) (reg rm) (cnd c)
180+
| `tSXTH, [|Reg rd; Reg rm; Imm c; _|] -> sx s16 (reg rd) (reg rm) (cnd c)
181+
| `tUXTB, [|Reg rd; Reg rm; Imm c; _|] -> ux s8 (reg rd) (reg rm) (cnd c)
182+
| `tUXTH, [|Reg rd; Reg rm; Imm c; _|] -> ux s16 (reg rd) (reg rm) (cnd c)
182183
| #opbit,_ as insn ->
183184
info "unhandled bit-wise instruction: %a" pp_insn insn;
184185
!!Insn.empty

0 commit comments

Comments
 (0)