1/* libs/pixelflinger/codeflinger/ARMAssemblerInterface.h
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18
19#ifndef ANDROID_ARMASSEMBLER_INTERFACE_H
20#define ANDROID_ARMASSEMBLER_INTERFACE_H
21
22#include <stdint.h>
23#include <sys/types.h>
24
25namespace android {
26
27// ----------------------------------------------------------------------------
28
29class ARMAssemblerInterface
30{
31public:
32    virtual ~ARMAssemblerInterface();
33
34    enum {
35        EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV,
36        HS = CS,
37        LO = CC
38    };
39    enum {
40        S = 1
41    };
42    enum {
43        LSL, LSR, ASR, ROR
44    };
45    enum {
46        ED, FD, EA, FA,
47        IB, IA, DB, DA
48    };
49    enum {
50        R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15,
51        SP = R13,
52        LR = R14,
53        PC = R15
54    };
55    enum {
56        #define LIST(rr) L##rr=1<<rr
57        LIST(R0), LIST(R1), LIST(R2), LIST(R3), LIST(R4), LIST(R5), LIST(R6),
58        LIST(R7), LIST(R8), LIST(R9), LIST(R10), LIST(R11), LIST(R12),
59        LIST(R13), LIST(R14), LIST(R15),
60        LIST(SP), LIST(LR), LIST(PC),
61        #undef LIST
62        LSAVED = LR4|LR5|LR6|LR7|LR8|LR9|LR10|LR11 | LLR
63    };
64
65    // -----------------------------------------------------------------------
66    // shifters and addressing modes
67    // -----------------------------------------------------------------------
68
69    // shifters...
70    static bool        isValidImmediate(uint32_t immed);
71    static int         buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm);
72
73    static uint32_t    imm(uint32_t immediate);
74    static uint32_t    reg_imm(int Rm, int type, uint32_t shift);
75    static uint32_t    reg_rrx(int Rm);
76    static uint32_t    reg_reg(int Rm, int type, int Rs);
77
78    // addressing modes...
79    // LDR(B)/STR(B)/PLD
80    // (immediate and Rm can be negative, which indicates U=0)
81    static uint32_t    immed12_pre(int32_t immed12, int W=0);
82    static uint32_t    immed12_post(int32_t immed12);
83    static uint32_t    reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0);
84    static uint32_t    reg_scale_post(int Rm, int type=0, uint32_t shift=0);
85
86    // LDRH/LDRSB/LDRSH/STRH
87    // (immediate and Rm can be negative, which indicates U=0)
88    static uint32_t    immed8_pre(int32_t immed8, int W=0);
89    static uint32_t    immed8_post(int32_t immed8);
90    static uint32_t    reg_pre(int Rm, int W=0);
91    static uint32_t    reg_post(int Rm);
92
93    // -----------------------------------------------------------------------
94    // basic instructions & code generation
95    // -----------------------------------------------------------------------
96
97    // generate the code
98    virtual void reset() = 0;
99    virtual int  generate(const char* name) = 0;
100    virtual void disassemble(const char* name) = 0;
101
102    // construct prolog and epilog
103    virtual void prolog() = 0;
104    virtual void epilog(uint32_t touched) = 0;
105    virtual void comment(const char* string) = 0;
106
107    // data processing...
108    enum {
109        opAND, opEOR, opSUB, opRSB, opADD, opADC, opSBC, opRSC,
110        opTST, opTEQ, opCMP, opCMN, opORR, opMOV, opBIC, opMVN
111    };
112
113    virtual void
114            dataProcessing( int opcode, int cc, int s,
115                            int Rd, int Rn,
116                            uint32_t Op2) = 0;
117
118    // multiply...
119    virtual void MLA(int cc, int s,
120                int Rd, int Rm, int Rs, int Rn) = 0;
121    virtual void MUL(int cc, int s,
122                int Rd, int Rm, int Rs) = 0;
123    virtual void UMULL(int cc, int s,
124                int RdLo, int RdHi, int Rm, int Rs) = 0;
125    virtual void UMUAL(int cc, int s,
126                int RdLo, int RdHi, int Rm, int Rs) = 0;
127    virtual void SMULL(int cc, int s,
128                int RdLo, int RdHi, int Rm, int Rs) = 0;
129    virtual void SMUAL(int cc, int s,
130                int RdLo, int RdHi, int Rm, int Rs) = 0;
131
132    // branches...
133    virtual void B(int cc, uint32_t* pc) = 0;
134    virtual void BL(int cc, uint32_t* pc) = 0;
135    virtual void BX(int cc, int Rn) = 0;
136
137    virtual void label(const char* theLabel) = 0;
138    virtual void B(int cc, const char* label) = 0;
139    virtual void BL(int cc, const char* label) = 0;
140
141    // valid only after generate() has been called
142    virtual uint32_t* pcForLabel(const char* label) = 0;
143
144    // data transfer...
145    virtual void LDR (int cc, int Rd,
146                int Rn, uint32_t offset = immed12_pre(0)) = 0;
147    virtual void LDRB(int cc, int Rd,
148                int Rn, uint32_t offset = immed12_pre(0)) = 0;
149    virtual void STR (int cc, int Rd,
150                int Rn, uint32_t offset = immed12_pre(0)) = 0;
151    virtual void STRB(int cc, int Rd,
152                int Rn, uint32_t offset = immed12_pre(0)) = 0;
153
154    virtual void LDRH (int cc, int Rd,
155                int Rn, uint32_t offset = immed8_pre(0)) = 0;
156    virtual void LDRSB(int cc, int Rd,
157                int Rn, uint32_t offset = immed8_pre(0)) = 0;
158    virtual void LDRSH(int cc, int Rd,
159                int Rn, uint32_t offset = immed8_pre(0)) = 0;
160    virtual void STRH (int cc, int Rd,
161                int Rn, uint32_t offset = immed8_pre(0)) = 0;
162
163    // block data transfer...
164    virtual void LDM(int cc, int dir,
165                int Rn, int W, uint32_t reg_list) = 0;
166    virtual void STM(int cc, int dir,
167                int Rn, int W, uint32_t reg_list) = 0;
168
169    // special...
170    virtual void SWP(int cc, int Rn, int Rd, int Rm) = 0;
171    virtual void SWPB(int cc, int Rn, int Rd, int Rm) = 0;
172    virtual void SWI(int cc, uint32_t comment) = 0;
173
174    // DSP instructions...
175    enum {
176        // B=0, T=1
177        //     yx
178        xyBB = 0, // 0000,
179        xyTB = 2, // 0010,
180        xyBT = 4, // 0100,
181        xyTT = 6, // 0110,
182        yB   = 0, // 0000,
183        yT   = 4, // 0100
184    };
185
186    virtual void PLD(int Rn, uint32_t offset) = 0;
187
188    virtual void CLZ(int cc, int Rd, int Rm) = 0;
189
190    virtual void QADD(int cc, int Rd, int Rm, int Rn) = 0;
191    virtual void QDADD(int cc, int Rd, int Rm, int Rn) = 0;
192    virtual void QSUB(int cc, int Rd, int Rm, int Rn) = 0;
193    virtual void QDSUB(int cc, int Rd, int Rm, int Rn) = 0;
194
195    virtual void SMUL(int cc, int xy,
196                int Rd, int Rm, int Rs) = 0;
197    virtual void SMULW(int cc, int y,
198                int Rd, int Rm, int Rs) = 0;
199    virtual void SMLA(int cc, int xy,
200                int Rd, int Rm, int Rs, int Rn) = 0;
201    virtual void SMLAL(int cc, int xy,
202                int RdHi, int RdLo, int Rs, int Rm) = 0;
203    virtual void SMLAW(int cc, int y,
204                int Rd, int Rm, int Rs, int Rn) = 0;
205
206    // byte/half word extract...
207    virtual void UXTB16(int cc, int Rd, int Rm, int rotate) = 0;
208
209    // bit manipulation...
210    virtual void UBFX(int cc, int Rd, int Rn, int lsb, int width) = 0;
211
212    // -----------------------------------------------------------------------
213    // convenience...
214    // -----------------------------------------------------------------------
215    inline void
216    ADC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
217        dataProcessing(opADC, cc, s, Rd, Rn, Op2);
218    }
219    inline void
220    ADD(int cc, int s, int Rd, int Rn, uint32_t Op2) {
221        dataProcessing(opADD, cc, s, Rd, Rn, Op2);
222    }
223    inline void
224    AND(int cc, int s, int Rd, int Rn, uint32_t Op2) {
225        dataProcessing(opAND, cc, s, Rd, Rn, Op2);
226    }
227    inline void
228    BIC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
229        dataProcessing(opBIC, cc, s, Rd, Rn, Op2);
230    }
231    inline void
232    EOR(int cc, int s, int Rd, int Rn, uint32_t Op2) {
233        dataProcessing(opEOR, cc, s, Rd, Rn, Op2);
234    }
235    inline void
236    MOV(int cc, int s, int Rd, uint32_t Op2) {
237        dataProcessing(opMOV, cc, s, Rd, 0, Op2);
238    }
239    inline void
240    MVN(int cc, int s, int Rd, uint32_t Op2) {
241        dataProcessing(opMVN, cc, s, Rd, 0, Op2);
242    }
243    inline void
244    ORR(int cc, int s, int Rd, int Rn, uint32_t Op2) {
245        dataProcessing(opORR, cc, s, Rd, Rn, Op2);
246    }
247    inline void
248    RSB(int cc, int s, int Rd, int Rn, uint32_t Op2) {
249        dataProcessing(opRSB, cc, s, Rd, Rn, Op2);
250    }
251    inline void
252    RSC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
253        dataProcessing(opRSC, cc, s, Rd, Rn, Op2);
254    }
255    inline void
256    SBC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
257        dataProcessing(opSBC, cc, s, Rd, Rn, Op2);
258    }
259    inline void
260    SUB(int cc, int s, int Rd, int Rn, uint32_t Op2) {
261        dataProcessing(opSUB, cc, s, Rd, Rn, Op2);
262    }
263    inline void
264    TEQ(int cc, int Rn, uint32_t Op2) {
265        dataProcessing(opTEQ, cc, 1, 0, Rn, Op2);
266    }
267    inline void
268    TST(int cc, int Rn, uint32_t Op2) {
269        dataProcessing(opTST, cc, 1, 0, Rn, Op2);
270    }
271    inline void
272    CMP(int cc, int Rn, uint32_t Op2) {
273        dataProcessing(opCMP, cc, 1, 0, Rn, Op2);
274    }
275    inline void
276    CMN(int cc, int Rn, uint32_t Op2) {
277        dataProcessing(opCMN, cc, 1, 0, Rn, Op2);
278    }
279
280    inline void SMULBB(int cc, int Rd, int Rm, int Rs) {
281        SMUL(cc, xyBB, Rd, Rm, Rs);    }
282    inline void SMULTB(int cc, int Rd, int Rm, int Rs) {
283        SMUL(cc, xyTB, Rd, Rm, Rs);    }
284    inline void SMULBT(int cc, int Rd, int Rm, int Rs) {
285        SMUL(cc, xyBT, Rd, Rm, Rs);    }
286    inline void SMULTT(int cc, int Rd, int Rm, int Rs) {
287        SMUL(cc, xyTT, Rd, Rm, Rs);    }
288
289    inline void SMULWB(int cc, int Rd, int Rm, int Rs) {
290        SMULW(cc, yB, Rd, Rm, Rs);    }
291    inline void SMULWT(int cc, int Rd, int Rm, int Rs) {
292        SMULW(cc, yT, Rd, Rm, Rs);    }
293
294    inline void
295    SMLABB(int cc, int Rd, int Rm, int Rs, int Rn) {
296        SMLA(cc, xyBB, Rd, Rm, Rs, Rn);    }
297    inline void
298    SMLATB(int cc, int Rd, int Rm, int Rs, int Rn) {
299        SMLA(cc, xyTB, Rd, Rm, Rs, Rn);    }
300    inline void
301    SMLABT(int cc, int Rd, int Rm, int Rs, int Rn) {
302        SMLA(cc, xyBT, Rd, Rm, Rs, Rn);    }
303    inline void
304    SMLATT(int cc, int Rd, int Rm, int Rs, int Rn) {
305        SMLA(cc, xyTT, Rd, Rm, Rs, Rn);    }
306
307    inline void
308    SMLALBB(int cc, int RdHi, int RdLo, int Rs, int Rm) {
309        SMLAL(cc, xyBB, RdHi, RdLo, Rs, Rm);    }
310    inline void
311    SMLALTB(int cc, int RdHi, int RdLo, int Rs, int Rm) {
312        SMLAL(cc, xyTB, RdHi, RdLo, Rs, Rm);    }
313    inline void
314    SMLALBT(int cc, int RdHi, int RdLo, int Rs, int Rm) {
315        SMLAL(cc, xyBT, RdHi, RdLo, Rs, Rm);    }
316    inline void
317    SMLALTT(int cc, int RdHi, int RdLo, int Rs, int Rm) {
318        SMLAL(cc, xyTT, RdHi, RdLo, Rs, Rm);    }
319
320    inline void
321    SMLAWB(int cc, int Rd, int Rm, int Rs, int Rn) {
322        SMLAW(cc, yB, Rd, Rm, Rs, Rn);    }
323    inline void
324    SMLAWT(int cc, int Rd, int Rm, int Rs, int Rn) {
325        SMLAW(cc, yT, Rd, Rm, Rs, Rn);    }
326};
327
328}; // namespace android
329
330#endif //ANDROID_ARMASSEMBLER_INTERFACE_H
331