ARMAssemblerInterface.h revision 2bc2b792782b304b15d8c48b54916a9b3fa3a7ac
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    enum {
66        CODEGEN_ARCH_ARM = 1, CODEGEN_ARCH_MIPS
67    };
68
69    // -----------------------------------------------------------------------
70    // shifters and addressing modes
71    // -----------------------------------------------------------------------
72
73    // these static versions are used for initializers on LDxx/STxx below
74    static uint32_t    __immed12_pre(int32_t immed12, int W=0);
75    static uint32_t    __immed8_pre(int32_t immed12, int W=0);
76
77    virtual bool        isValidImmediate(uint32_t immed) = 0;
78    virtual int         buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm) = 0;
79
80    virtual uint32_t    imm(uint32_t immediate) = 0;
81    virtual uint32_t    reg_imm(int Rm, int type, uint32_t shift) = 0;
82    virtual uint32_t    reg_rrx(int Rm) = 0;
83    virtual uint32_t    reg_reg(int Rm, int type, int Rs) = 0;
84
85    // addressing modes...
86    // LDR(B)/STR(B)/PLD
87    // (immediate and Rm can be negative, which indicates U=0)
88    virtual uint32_t    immed12_pre(int32_t immed12, int W=0) = 0;
89    virtual uint32_t    immed12_post(int32_t immed12) = 0;
90    virtual uint32_t    reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0) = 0;
91    virtual uint32_t    reg_scale_post(int Rm, int type=0, uint32_t shift=0) = 0;
92
93    // LDRH/LDRSB/LDRSH/STRH
94    // (immediate and Rm can be negative, which indicates U=0)
95    virtual uint32_t    immed8_pre(int32_t immed8, int W=0) = 0;
96    virtual uint32_t    immed8_post(int32_t immed8) = 0;
97    virtual uint32_t    reg_pre(int Rm, int W=0) = 0;
98    virtual uint32_t    reg_post(int Rm) = 0;
99
100    // -----------------------------------------------------------------------
101    // basic instructions & code generation
102    // -----------------------------------------------------------------------
103
104    // generate the code
105    virtual void reset() = 0;
106    virtual int  generate(const char* name) = 0;
107    virtual void disassemble(const char* name) = 0;
108    virtual int  getCodegenArch() = 0;
109
110    // construct prolog and epilog
111    virtual void prolog() = 0;
112    virtual void epilog(uint32_t touched) = 0;
113    virtual void comment(const char* string) = 0;
114
115    // data processing...
116    enum {
117        opAND, opEOR, opSUB, opRSB, opADD, opADC, opSBC, opRSC,
118        opTST, opTEQ, opCMP, opCMN, opORR, opMOV, opBIC, opMVN
119    };
120
121    virtual void
122            dataProcessing( int opcode, int cc, int s,
123                            int Rd, int Rn,
124                            uint32_t Op2) = 0;
125
126    // multiply...
127    virtual void MLA(int cc, int s,
128                int Rd, int Rm, int Rs, int Rn) = 0;
129    virtual void MUL(int cc, int s,
130                int Rd, int Rm, int Rs) = 0;
131    virtual void UMULL(int cc, int s,
132                int RdLo, int RdHi, int Rm, int Rs) = 0;
133    virtual void UMUAL(int cc, int s,
134                int RdLo, int RdHi, int Rm, int Rs) = 0;
135    virtual void SMULL(int cc, int s,
136                int RdLo, int RdHi, int Rm, int Rs) = 0;
137    virtual void SMUAL(int cc, int s,
138                int RdLo, int RdHi, int Rm, int Rs) = 0;
139
140    // branches...
141    virtual void B(int cc, uint32_t* pc) = 0;
142    virtual void BL(int cc, uint32_t* pc) = 0;
143    virtual void BX(int cc, int Rn) = 0;
144
145    virtual void label(const char* theLabel) = 0;
146    virtual void B(int cc, const char* label) = 0;
147    virtual void BL(int cc, const char* label) = 0;
148
149    // valid only after generate() has been called
150    virtual uint32_t* pcForLabel(const char* label) = 0;
151
152    // data transfer...
153    virtual void LDR (int cc, int Rd,
154                int Rn, uint32_t offset = __immed12_pre(0)) = 0;
155    virtual void LDRB(int cc, int Rd,
156                int Rn, uint32_t offset = __immed12_pre(0)) = 0;
157    virtual void STR (int cc, int Rd,
158                int Rn, uint32_t offset = __immed12_pre(0)) = 0;
159    virtual void STRB(int cc, int Rd,
160                int Rn, uint32_t offset = __immed12_pre(0)) = 0;
161
162    virtual void LDRH (int cc, int Rd,
163                int Rn, uint32_t offset = __immed8_pre(0)) = 0;
164    virtual void LDRSB(int cc, int Rd,
165                int Rn, uint32_t offset = __immed8_pre(0)) = 0;
166    virtual void LDRSH(int cc, int Rd,
167                int Rn, uint32_t offset = __immed8_pre(0)) = 0;
168    virtual void STRH (int cc, int Rd,
169                int Rn, uint32_t offset = __immed8_pre(0)) = 0;
170
171    // block data transfer...
172    virtual void LDM(int cc, int dir,
173                int Rn, int W, uint32_t reg_list) = 0;
174    virtual void STM(int cc, int dir,
175                int Rn, int W, uint32_t reg_list) = 0;
176
177    // special...
178    virtual void SWP(int cc, int Rn, int Rd, int Rm) = 0;
179    virtual void SWPB(int cc, int Rn, int Rd, int Rm) = 0;
180    virtual void SWI(int cc, uint32_t comment) = 0;
181
182    // DSP instructions...
183    enum {
184        // B=0, T=1
185        //     yx
186        xyBB = 0, // 0000,
187        xyTB = 2, // 0010,
188        xyBT = 4, // 0100,
189        xyTT = 6, // 0110,
190        yB   = 0, // 0000,
191        yT   = 4, // 0100
192    };
193
194    virtual void PLD(int Rn, uint32_t offset) = 0;
195
196    virtual void CLZ(int cc, int Rd, int Rm) = 0;
197
198    virtual void QADD(int cc, int Rd, int Rm, int Rn) = 0;
199    virtual void QDADD(int cc, int Rd, int Rm, int Rn) = 0;
200    virtual void QSUB(int cc, int Rd, int Rm, int Rn) = 0;
201    virtual void QDSUB(int cc, int Rd, int Rm, int Rn) = 0;
202
203    virtual void SMUL(int cc, int xy,
204                int Rd, int Rm, int Rs) = 0;
205    virtual void SMULW(int cc, int y,
206                int Rd, int Rm, int Rs) = 0;
207    virtual void SMLA(int cc, int xy,
208                int Rd, int Rm, int Rs, int Rn) = 0;
209    virtual void SMLAL(int cc, int xy,
210                int RdHi, int RdLo, int Rs, int Rm) = 0;
211    virtual void SMLAW(int cc, int y,
212                int Rd, int Rm, int Rs, int Rn) = 0;
213
214    // byte/half word extract...
215    virtual void UXTB16(int cc, int Rd, int Rm, int rotate) = 0;
216
217    // bit manipulation...
218    virtual void UBFX(int cc, int Rd, int Rn, int lsb, int width) = 0;
219
220    // -----------------------------------------------------------------------
221    // convenience...
222    // -----------------------------------------------------------------------
223    inline void
224    ADC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
225        dataProcessing(opADC, cc, s, Rd, Rn, Op2);
226    }
227    inline void
228    ADD(int cc, int s, int Rd, int Rn, uint32_t Op2) {
229        dataProcessing(opADD, cc, s, Rd, Rn, Op2);
230    }
231    inline void
232    AND(int cc, int s, int Rd, int Rn, uint32_t Op2) {
233        dataProcessing(opAND, cc, s, Rd, Rn, Op2);
234    }
235    inline void
236    BIC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
237        dataProcessing(opBIC, cc, s, Rd, Rn, Op2);
238    }
239    inline void
240    EOR(int cc, int s, int Rd, int Rn, uint32_t Op2) {
241        dataProcessing(opEOR, cc, s, Rd, Rn, Op2);
242    }
243    inline void
244    MOV(int cc, int s, int Rd, uint32_t Op2) {
245        dataProcessing(opMOV, cc, s, Rd, 0, Op2);
246    }
247    inline void
248    MVN(int cc, int s, int Rd, uint32_t Op2) {
249        dataProcessing(opMVN, cc, s, Rd, 0, Op2);
250    }
251    inline void
252    ORR(int cc, int s, int Rd, int Rn, uint32_t Op2) {
253        dataProcessing(opORR, cc, s, Rd, Rn, Op2);
254    }
255    inline void
256    RSB(int cc, int s, int Rd, int Rn, uint32_t Op2) {
257        dataProcessing(opRSB, cc, s, Rd, Rn, Op2);
258    }
259    inline void
260    RSC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
261        dataProcessing(opRSC, cc, s, Rd, Rn, Op2);
262    }
263    inline void
264    SBC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
265        dataProcessing(opSBC, cc, s, Rd, Rn, Op2);
266    }
267    inline void
268    SUB(int cc, int s, int Rd, int Rn, uint32_t Op2) {
269        dataProcessing(opSUB, cc, s, Rd, Rn, Op2);
270    }
271    inline void
272    TEQ(int cc, int Rn, uint32_t Op2) {
273        dataProcessing(opTEQ, cc, 1, 0, Rn, Op2);
274    }
275    inline void
276    TST(int cc, int Rn, uint32_t Op2) {
277        dataProcessing(opTST, cc, 1, 0, Rn, Op2);
278    }
279    inline void
280    CMP(int cc, int Rn, uint32_t Op2) {
281        dataProcessing(opCMP, cc, 1, 0, Rn, Op2);
282    }
283    inline void
284    CMN(int cc, int Rn, uint32_t Op2) {
285        dataProcessing(opCMN, cc, 1, 0, Rn, Op2);
286    }
287
288    inline void SMULBB(int cc, int Rd, int Rm, int Rs) {
289        SMUL(cc, xyBB, Rd, Rm, Rs);    }
290    inline void SMULTB(int cc, int Rd, int Rm, int Rs) {
291        SMUL(cc, xyTB, Rd, Rm, Rs);    }
292    inline void SMULBT(int cc, int Rd, int Rm, int Rs) {
293        SMUL(cc, xyBT, Rd, Rm, Rs);    }
294    inline void SMULTT(int cc, int Rd, int Rm, int Rs) {
295        SMUL(cc, xyTT, Rd, Rm, Rs);    }
296
297    inline void SMULWB(int cc, int Rd, int Rm, int Rs) {
298        SMULW(cc, yB, Rd, Rm, Rs);    }
299    inline void SMULWT(int cc, int Rd, int Rm, int Rs) {
300        SMULW(cc, yT, Rd, Rm, Rs);    }
301
302    inline void
303    SMLABB(int cc, int Rd, int Rm, int Rs, int Rn) {
304        SMLA(cc, xyBB, Rd, Rm, Rs, Rn);    }
305    inline void
306    SMLATB(int cc, int Rd, int Rm, int Rs, int Rn) {
307        SMLA(cc, xyTB, Rd, Rm, Rs, Rn);    }
308    inline void
309    SMLABT(int cc, int Rd, int Rm, int Rs, int Rn) {
310        SMLA(cc, xyBT, Rd, Rm, Rs, Rn);    }
311    inline void
312    SMLATT(int cc, int Rd, int Rm, int Rs, int Rn) {
313        SMLA(cc, xyTT, Rd, Rm, Rs, Rn);    }
314
315    inline void
316    SMLALBB(int cc, int RdHi, int RdLo, int Rs, int Rm) {
317        SMLAL(cc, xyBB, RdHi, RdLo, Rs, Rm);    }
318    inline void
319    SMLALTB(int cc, int RdHi, int RdLo, int Rs, int Rm) {
320        SMLAL(cc, xyTB, RdHi, RdLo, Rs, Rm);    }
321    inline void
322    SMLALBT(int cc, int RdHi, int RdLo, int Rs, int Rm) {
323        SMLAL(cc, xyBT, RdHi, RdLo, Rs, Rm);    }
324    inline void
325    SMLALTT(int cc, int RdHi, int RdLo, int Rs, int Rm) {
326        SMLAL(cc, xyTT, RdHi, RdLo, Rs, Rm);    }
327
328    inline void
329    SMLAWB(int cc, int Rd, int Rm, int Rs, int Rn) {
330        SMLAW(cc, yB, Rd, Rm, Rs, Rn);    }
331    inline void
332    SMLAWT(int cc, int Rd, int Rm, int Rs, int Rn) {
333        SMLAW(cc, yT, Rd, Rm, Rs, Rn);    }
334};
335
336}; // namespace android
337
338#endif //ANDROID_ARMASSEMBLER_INTERFACE_H
339