xref: /aosp_15_r20/external/llvm/lib/Target/ARM/README-Thumb.txt (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker// Random ideas for the ARM backend (Thumb specific).
3*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker* Add support for compiling functions in both ARM and Thumb mode, then taking
6*9880d681SAndroid Build Coastguard Worker  the smallest.
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Worker* Add support for compiling individual basic blocks in thumb mode, when in a
9*9880d681SAndroid Build Coastguard Worker  larger ARM function.  This can be used for presumed cold code, like paths
10*9880d681SAndroid Build Coastguard Worker  to abort (failure path of asserts), EH handling code, etc.
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Worker* Thumb doesn't have normal pre/post increment addressing modes, but you can
13*9880d681SAndroid Build Coastguard Worker  load/store 32-bit integers with pre/postinc by using load/store multiple
14*9880d681SAndroid Build Coastguard Worker  instrs with a single register.
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker* Make better use of high registers r8, r10, r11, r12 (ip). Some variants of add
17*9880d681SAndroid Build Coastguard Worker  and cmp instructions can use high registers. Also, we can use them as
18*9880d681SAndroid Build Coastguard Worker  temporaries to spill values into.
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker* In thumb mode, short, byte, and bool preferred alignments are currently set
21*9880d681SAndroid Build Coastguard Worker  to 4 to accommodate ISA restriction (i.e. add sp, #imm, imm must be multiple
22*9880d681SAndroid Build Coastguard Worker  of 4).
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard WorkerPotential jumptable improvements:
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker* If we know function size is less than (1 << 16) * 2 bytes, we can use 16-bit
29*9880d681SAndroid Build Coastguard Worker  jumptable entries (e.g. (L1 - L2) >> 1). Or even smaller entries if the
30*9880d681SAndroid Build Coastguard Worker  function is even smaller. This also applies to ARM.
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker* Thumb jumptable codegen can improve given some help from the assembler. This
33*9880d681SAndroid Build Coastguard Worker  is what we generate right now:
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker	.set PCRELV0, (LJTI1_0_0-(LPCRELL0+4))
36*9880d681SAndroid Build Coastguard WorkerLPCRELL0:
37*9880d681SAndroid Build Coastguard Worker	mov r1, #PCRELV0
38*9880d681SAndroid Build Coastguard Worker	add r1, pc
39*9880d681SAndroid Build Coastguard Worker	ldr r0, [r0, r1]
40*9880d681SAndroid Build Coastguard Worker	mov pc, r0
41*9880d681SAndroid Build Coastguard Worker	.align	2
42*9880d681SAndroid Build Coastguard WorkerLJTI1_0_0:
43*9880d681SAndroid Build Coastguard Worker	.long	 LBB1_3
44*9880d681SAndroid Build Coastguard Worker        ...
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard WorkerNote there is another pc relative add that we can take advantage of.
47*9880d681SAndroid Build Coastguard Worker     add r1, pc, #imm_8 * 4
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard WorkerWe should be able to generate:
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard WorkerLPCRELL0:
52*9880d681SAndroid Build Coastguard Worker	add r1, LJTI1_0_0
53*9880d681SAndroid Build Coastguard Worker	ldr r0, [r0, r1]
54*9880d681SAndroid Build Coastguard Worker	mov pc, r0
55*9880d681SAndroid Build Coastguard Worker	.align	2
56*9880d681SAndroid Build Coastguard WorkerLJTI1_0_0:
57*9880d681SAndroid Build Coastguard Worker	.long	 LBB1_3
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Workerif the assembler can translate the add to:
60*9880d681SAndroid Build Coastguard Worker       add r1, pc, #((LJTI1_0_0-(LPCRELL0+4))&0xfffffffc)
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard WorkerNote the assembler also does something similar to constpool load:
63*9880d681SAndroid Build Coastguard WorkerLPCRELL0:
64*9880d681SAndroid Build Coastguard Worker     ldr r0, LCPI1_0
65*9880d681SAndroid Build Coastguard Worker=>
66*9880d681SAndroid Build Coastguard Worker     ldr r0, pc, #((LCPI1_0-(LPCRELL0+4))&0xfffffffc)
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard WorkerWe compile the following:
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Workerdefine i16 @func_entry_2E_ce(i32 %i) {
74*9880d681SAndroid Build Coastguard Worker        switch i32 %i, label %bb12.exitStub [
75*9880d681SAndroid Build Coastguard Worker                 i32 0, label %bb4.exitStub
76*9880d681SAndroid Build Coastguard Worker                 i32 1, label %bb9.exitStub
77*9880d681SAndroid Build Coastguard Worker                 i32 2, label %bb4.exitStub
78*9880d681SAndroid Build Coastguard Worker                 i32 3, label %bb4.exitStub
79*9880d681SAndroid Build Coastguard Worker                 i32 7, label %bb9.exitStub
80*9880d681SAndroid Build Coastguard Worker                 i32 8, label %bb.exitStub
81*9880d681SAndroid Build Coastguard Worker                 i32 9, label %bb9.exitStub
82*9880d681SAndroid Build Coastguard Worker        ]
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Workerbb12.exitStub:
85*9880d681SAndroid Build Coastguard Worker        ret i16 0
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Workerbb4.exitStub:
88*9880d681SAndroid Build Coastguard Worker        ret i16 1
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Workerbb9.exitStub:
91*9880d681SAndroid Build Coastguard Worker        ret i16 2
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Workerbb.exitStub:
94*9880d681SAndroid Build Coastguard Worker        ret i16 3
95*9880d681SAndroid Build Coastguard Worker}
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Workerinto:
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker_func_entry_2E_ce:
100*9880d681SAndroid Build Coastguard Worker        mov r2, #1
101*9880d681SAndroid Build Coastguard Worker        lsl r2, r0
102*9880d681SAndroid Build Coastguard Worker        cmp r0, #9
103*9880d681SAndroid Build Coastguard Worker        bhi LBB1_4      @bb12.exitStub
104*9880d681SAndroid Build Coastguard WorkerLBB1_1: @newFuncRoot
105*9880d681SAndroid Build Coastguard Worker        mov r1, #13
106*9880d681SAndroid Build Coastguard Worker        tst r2, r1
107*9880d681SAndroid Build Coastguard Worker        bne LBB1_5      @bb4.exitStub
108*9880d681SAndroid Build Coastguard WorkerLBB1_2: @newFuncRoot
109*9880d681SAndroid Build Coastguard Worker        ldr r1, LCPI1_0
110*9880d681SAndroid Build Coastguard Worker        tst r2, r1
111*9880d681SAndroid Build Coastguard Worker        bne LBB1_6      @bb9.exitStub
112*9880d681SAndroid Build Coastguard WorkerLBB1_3: @newFuncRoot
113*9880d681SAndroid Build Coastguard Worker        mov r1, #1
114*9880d681SAndroid Build Coastguard Worker        lsl r1, r1, #8
115*9880d681SAndroid Build Coastguard Worker        tst r2, r1
116*9880d681SAndroid Build Coastguard Worker        bne LBB1_7      @bb.exitStub
117*9880d681SAndroid Build Coastguard WorkerLBB1_4: @bb12.exitStub
118*9880d681SAndroid Build Coastguard Worker        mov r0, #0
119*9880d681SAndroid Build Coastguard Worker        bx lr
120*9880d681SAndroid Build Coastguard WorkerLBB1_5: @bb4.exitStub
121*9880d681SAndroid Build Coastguard Worker        mov r0, #1
122*9880d681SAndroid Build Coastguard Worker        bx lr
123*9880d681SAndroid Build Coastguard WorkerLBB1_6: @bb9.exitStub
124*9880d681SAndroid Build Coastguard Worker        mov r0, #2
125*9880d681SAndroid Build Coastguard Worker        bx lr
126*9880d681SAndroid Build Coastguard WorkerLBB1_7: @bb.exitStub
127*9880d681SAndroid Build Coastguard Worker        mov r0, #3
128*9880d681SAndroid Build Coastguard Worker        bx lr
129*9880d681SAndroid Build Coastguard WorkerLBB1_8:
130*9880d681SAndroid Build Coastguard Worker        .align  2
131*9880d681SAndroid Build Coastguard WorkerLCPI1_0:
132*9880d681SAndroid Build Coastguard Worker        .long   642
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Workergcc compiles to:
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker	cmp	r0, #9
138*9880d681SAndroid Build Coastguard Worker	@ lr needed for prologue
139*9880d681SAndroid Build Coastguard Worker	bhi	L2
140*9880d681SAndroid Build Coastguard Worker	ldr	r3, L11
141*9880d681SAndroid Build Coastguard Worker	mov	r2, #1
142*9880d681SAndroid Build Coastguard Worker	mov	r1, r2, asl r0
143*9880d681SAndroid Build Coastguard Worker	ands	r0, r3, r2, asl r0
144*9880d681SAndroid Build Coastguard Worker	movne	r0, #2
145*9880d681SAndroid Build Coastguard Worker	bxne	lr
146*9880d681SAndroid Build Coastguard Worker	tst	r1, #13
147*9880d681SAndroid Build Coastguard Worker	beq	L9
148*9880d681SAndroid Build Coastguard WorkerL3:
149*9880d681SAndroid Build Coastguard Worker	mov	r0, r2
150*9880d681SAndroid Build Coastguard Worker	bx	lr
151*9880d681SAndroid Build Coastguard WorkerL9:
152*9880d681SAndroid Build Coastguard Worker	tst	r1, #256
153*9880d681SAndroid Build Coastguard Worker	movne	r0, #3
154*9880d681SAndroid Build Coastguard Worker	bxne	lr
155*9880d681SAndroid Build Coastguard WorkerL2:
156*9880d681SAndroid Build Coastguard Worker	mov	r0, #0
157*9880d681SAndroid Build Coastguard Worker	bx	lr
158*9880d681SAndroid Build Coastguard WorkerL12:
159*9880d681SAndroid Build Coastguard Worker	.align 2
160*9880d681SAndroid Build Coastguard WorkerL11:
161*9880d681SAndroid Build Coastguard Worker	.long	642
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard WorkerGCC is doing a couple of clever things here:
165*9880d681SAndroid Build Coastguard Worker  1. It is predicating one of the returns.  This isn't a clear win though: in
166*9880d681SAndroid Build Coastguard Worker     cases where that return isn't taken, it is replacing one condbranch with
167*9880d681SAndroid Build Coastguard Worker     two 'ne' predicated instructions.
168*9880d681SAndroid Build Coastguard Worker  2. It is sinking the shift of "1 << i" into the tst, and using ands instead of
169*9880d681SAndroid Build Coastguard Worker     tst.  This will probably require whole function isel.
170*9880d681SAndroid Build Coastguard Worker  3. GCC emits:
171*9880d681SAndroid Build Coastguard Worker  	tst	r1, #256
172*9880d681SAndroid Build Coastguard Worker     we emit:
173*9880d681SAndroid Build Coastguard Worker        mov r1, #1
174*9880d681SAndroid Build Coastguard Worker        lsl r1, r1, #8
175*9880d681SAndroid Build Coastguard Worker        tst r2, r1
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard WorkerWhen spilling in thumb mode and the sp offset is too large to fit in the ldr /
180*9880d681SAndroid Build Coastguard Workerstr offset field, we load the offset from a constpool entry and add it to sp:
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Workerldr r2, LCPI
183*9880d681SAndroid Build Coastguard Workeradd r2, sp
184*9880d681SAndroid Build Coastguard Workerldr r2, [r2]
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard WorkerThese instructions preserve the condition code which is important if the spill
187*9880d681SAndroid Build Coastguard Workeris between a cmp and a bcc instruction. However, we can use the (potentially)
188*9880d681SAndroid Build Coastguard Workercheaper sequnce if we know it's ok to clobber the condition register.
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Workeradd r2, sp, #255 * 4
191*9880d681SAndroid Build Coastguard Workeradd r2, #132
192*9880d681SAndroid Build Coastguard Workerldr r2, [r2, #7 * 4]
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard WorkerThis is especially bad when dynamic alloca is used. The all fixed size stack
195*9880d681SAndroid Build Coastguard Workerobjects are referenced off the frame pointer with negative offsets. See
196*9880d681SAndroid Build Coastguard Workeroggenc for an example.
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard WorkerPoor codegen test/CodeGen/ARM/select.ll f7:
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker	ldr r5, LCPI1_0
203*9880d681SAndroid Build Coastguard WorkerLPC0:
204*9880d681SAndroid Build Coastguard Worker	add r5, pc
205*9880d681SAndroid Build Coastguard Worker	ldr r6, LCPI1_1
206*9880d681SAndroid Build Coastguard Worker	ldr r2, LCPI1_2
207*9880d681SAndroid Build Coastguard Worker	mov r3, r6
208*9880d681SAndroid Build Coastguard Worker	mov lr, pc
209*9880d681SAndroid Build Coastguard Worker	bx r5
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard WorkerMake register allocator / spiller smarter so we can re-materialize "mov r, imm",
214*9880d681SAndroid Build Coastguard Workeretc. Almost all Thumb instructions clobber condition code.
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard WorkerThumb load / store address mode offsets are scaled. The values kept in the
219*9880d681SAndroid Build Coastguard Workerinstruction operands are pre-scale values. This probably ought to be changed
220*9880d681SAndroid Build Coastguard Workerto avoid extra work when we convert Thumb2 instructions to Thumb1 instructions.
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard WorkerWe need to make (some of the) Thumb1 instructions predicable. That will allow
225*9880d681SAndroid Build Coastguard Workershrinking of predicated Thumb2 instructions. To allow this, we need to be able
226*9880d681SAndroid Build Coastguard Workerto toggle the 's' bit since they do not set CPSR when they are inside IT blocks.
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard WorkerMake use of hi register variants of cmp: tCMPhir / tCMPZhir.
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
233*9880d681SAndroid Build Coastguard Worker
234*9880d681SAndroid Build Coastguard WorkerThumb1 immediate field sometimes keep pre-scaled values. See
235*9880d681SAndroid Build Coastguard WorkerThumbRegisterInfo::eliminateFrameIndex. This is inconsistent from ARM and
236*9880d681SAndroid Build Coastguard WorkerThumb2.
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard WorkerRather than having tBR_JTr print a ".align 2" and constant island pass pad it,
241*9880d681SAndroid Build Coastguard Workeradd a target specific ALIGN instruction instead. That way, GetInstSizeInBytes
242*9880d681SAndroid Build Coastguard Workerwon't have to over-estimate. It can also be used for loop alignment pass.
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard WorkerWe generate conditional code for icmp when we don't need to. This code:
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Worker  int foo(int s) {
249*9880d681SAndroid Build Coastguard Worker    return s == 1;
250*9880d681SAndroid Build Coastguard Worker  }
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Workerproduces:
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Workerfoo:
255*9880d681SAndroid Build Coastguard Worker        cmp     r0, #1
256*9880d681SAndroid Build Coastguard Worker        mov.w   r0, #0
257*9880d681SAndroid Build Coastguard Worker        it      eq
258*9880d681SAndroid Build Coastguard Worker        moveq   r0, #1
259*9880d681SAndroid Build Coastguard Worker        bx      lr
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Workerwhen it could use subs + adcs. This is GCC PR46975.
262