ARMAssemblerInterface.h revision 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53
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    // -----------------------------------------------------------------------
207    // convenience...
208    // -----------------------------------------------------------------------
209    inline void
210    ADC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
211        dataProcessing(opADC, cc, s, Rd, Rn, Op2);
212    }
213    inline void
214    ADD(int cc, int s, int Rd, int Rn, uint32_t Op2) {
215        dataProcessing(opADD, cc, s, Rd, Rn, Op2);
216    }
217    inline void
218    AND(int cc, int s, int Rd, int Rn, uint32_t Op2) {
219        dataProcessing(opAND, cc, s, Rd, Rn, Op2);
220    }
221    inline void
222    BIC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
223        dataProcessing(opBIC, cc, s, Rd, Rn, Op2);
224    }
225    inline void
226    EOR(int cc, int s, int Rd, int Rn, uint32_t Op2) {
227        dataProcessing(opEOR, cc, s, Rd, Rn, Op2);
228    }
229    inline void
230    MOV(int cc, int s, int Rd, uint32_t Op2) {
231        dataProcessing(opMOV, cc, s, Rd, 0, Op2);
232    }
233    inline void
234    MVN(int cc, int s, int Rd, uint32_t Op2) {
235        dataProcessing(opMVN, cc, s, Rd, 0, Op2);
236    }
237    inline void
238    ORR(int cc, int s, int Rd, int Rn, uint32_t Op2) {
239        dataProcessing(opORR, cc, s, Rd, Rn, Op2);
240    }
241    inline void
242    RSB(int cc, int s, int Rd, int Rn, uint32_t Op2) {
243        dataProcessing(opRSB, cc, s, Rd, Rn, Op2);
244    }
245    inline void
246    RSC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
247        dataProcessing(opRSC, cc, s, Rd, Rn, Op2);
248    }
249    inline void
250    SBC(int cc, int s, int Rd, int Rn, uint32_t Op2) {
251        dataProcessing(opSBC, cc, s, Rd, Rn, Op2);
252    }
253    inline void
254    SUB(int cc, int s, int Rd, int Rn, uint32_t Op2) {
255        dataProcessing(opSUB, cc, s, Rd, Rn, Op2);
256    }
257    inline void
258    TEQ(int cc, int Rn, uint32_t Op2) {
259        dataProcessing(opTEQ, cc, 1, 0, Rn, Op2);
260    }
261    inline void
262    TST(int cc, int Rn, uint32_t Op2) {
263        dataProcessing(opTST, cc, 1, 0, Rn, Op2);
264    }
265    inline void
266    CMP(int cc, int Rn, uint32_t Op2) {
267        dataProcessing(opCMP, cc, 1, 0, Rn, Op2);
268    }
269    inline void
270    CMN(int cc, int Rn, uint32_t Op2) {
271        dataProcessing(opCMN, cc, 1, 0, Rn, Op2);
272    }
273
274    inline void SMULBB(int cc, int Rd, int Rm, int Rs) {
275        SMUL(cc, xyBB, Rd, Rm, Rs);    }
276    inline void SMULTB(int cc, int Rd, int Rm, int Rs) {
277        SMUL(cc, xyTB, Rd, Rm, Rs);    }
278    inline void SMULBT(int cc, int Rd, int Rm, int Rs) {
279        SMUL(cc, xyBT, Rd, Rm, Rs);    }
280    inline void SMULTT(int cc, int Rd, int Rm, int Rs) {
281        SMUL(cc, xyTT, Rd, Rm, Rs);    }
282
283    inline void SMULWB(int cc, int Rd, int Rm, int Rs) {
284        SMULW(cc, yB, Rd, Rm, Rs);    }
285    inline void SMULWT(int cc, int Rd, int Rm, int Rs) {
286        SMULW(cc, yT, Rd, Rm, Rs);    }
287
288    inline void
289    SMLABB(int cc, int Rd, int Rm, int Rs, int Rn) {
290        SMLA(cc, xyBB, Rd, Rm, Rs, Rn);    }
291    inline void
292    SMLATB(int cc, int Rd, int Rm, int Rs, int Rn) {
293        SMLA(cc, xyTB, Rd, Rm, Rs, Rn);    }
294    inline void
295    SMLABT(int cc, int Rd, int Rm, int Rs, int Rn) {
296        SMLA(cc, xyBT, Rd, Rm, Rs, Rn);    }
297    inline void
298    SMLATT(int cc, int Rd, int Rm, int Rs, int Rn) {
299        SMLA(cc, xyTT, Rd, Rm, Rs, Rn);    }
300
301    inline void
302    SMLALBB(int cc, int RdHi, int RdLo, int Rs, int Rm) {
303        SMLAL(cc, xyBB, RdHi, RdLo, Rs, Rm);    }
304    inline void
305    SMLALTB(int cc, int RdHi, int RdLo, int Rs, int Rm) {
306        SMLAL(cc, xyTB, RdHi, RdLo, Rs, Rm);    }
307    inline void
308    SMLALBT(int cc, int RdHi, int RdLo, int Rs, int Rm) {
309        SMLAL(cc, xyBT, RdHi, RdLo, Rs, Rm);    }
310    inline void
311    SMLALTT(int cc, int RdHi, int RdLo, int Rs, int Rm) {
312        SMLAL(cc, xyTT, RdHi, RdLo, Rs, Rm);    }
313
314    inline void
315    SMLAWB(int cc, int Rd, int Rm, int Rs, int Rn) {
316        SMLAW(cc, yB, Rd, Rm, Rs, Rn);    }
317    inline void
318    SMLAWT(int cc, int Rd, int Rm, int Rs, int Rn) {
319        SMLAW(cc, yT, Rd, Rm, Rs, Rn);    }
320};
321
322}; // namespace android
323
324#endif //ANDROID_ARMASSEMBLER_INTERFACE_H
325