1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *  * Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in
12 *    the documentation and/or other materials provided with the
13 *    distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#ifndef ANDROID_ARMTOARM64ASSEMBLER_H
30#define ANDROID_ARMTOARM64ASSEMBLER_H
31
32#include <stdint.h>
33#include <sys/types.h>
34
35#include "tinyutils/smartpointer.h"
36#include "utils/Vector.h"
37#include "utils/KeyedVector.h"
38
39#include "tinyutils/smartpointer.h"
40#include "codeflinger/ARMAssemblerInterface.h"
41#include "codeflinger/CodeCache.h"
42
43namespace android {
44
45// ----------------------------------------------------------------------------
46
47class ArmToArm64Assembler : public ARMAssemblerInterface
48{
49public:
50                ArmToArm64Assembler(const sp<Assembly>& assembly);
51                ArmToArm64Assembler(void *base);
52    virtual     ~ArmToArm64Assembler();
53
54    uint32_t*   base() const;
55    uint32_t*   pc() const;
56
57
58    void        disassemble(const char* name);
59
60    // ------------------------------------------------------------------------
61    // ARMAssemblerInterface...
62    // ------------------------------------------------------------------------
63
64    virtual void    reset();
65
66    virtual int     generate(const char* name);
67    virtual int     getCodegenArch();
68
69    virtual void    prolog();
70    virtual void    epilog(uint32_t touched);
71    virtual void    comment(const char* string);
72
73
74    // -----------------------------------------------------------------------
75    // shifters and addressing modes
76    // -----------------------------------------------------------------------
77
78    // shifters...
79    virtual bool        isValidImmediate(uint32_t immed);
80    virtual int         buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm);
81
82    virtual uint32_t    imm(uint32_t immediate);
83    virtual uint32_t    reg_imm(int Rm, int type, uint32_t shift);
84    virtual uint32_t    reg_rrx(int Rm);
85    virtual uint32_t    reg_reg(int Rm, int type, int Rs);
86
87    // addressing modes...
88    virtual uint32_t    immed12_pre(int32_t immed12, int W=0);
89    virtual uint32_t    immed12_post(int32_t immed12);
90    virtual uint32_t    reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0);
91    virtual uint32_t    reg_scale_post(int Rm, int type=0, uint32_t shift=0);
92    virtual uint32_t    immed8_pre(int32_t immed8, int W=0);
93    virtual uint32_t    immed8_post(int32_t immed8);
94    virtual uint32_t    reg_pre(int Rm, int W=0);
95    virtual uint32_t    reg_post(int Rm);
96
97
98    virtual void    dataProcessing(int opcode, int cc, int s,
99                                int Rd, int Rn,
100                                uint32_t Op2);
101    virtual void MLA(int cc, int s,
102                int Rd, int Rm, int Rs, int Rn);
103    virtual void MUL(int cc, int s,
104                int Rd, int Rm, int Rs);
105    virtual void UMULL(int cc, int s,
106                int RdLo, int RdHi, int Rm, int Rs);
107    virtual void UMUAL(int cc, int s,
108                int RdLo, int RdHi, int Rm, int Rs);
109    virtual void SMULL(int cc, int s,
110                int RdLo, int RdHi, int Rm, int Rs);
111    virtual void SMUAL(int cc, int s,
112                int RdLo, int RdHi, int Rm, int Rs);
113
114    virtual void B(int cc, uint32_t* pc);
115    virtual void BL(int cc, uint32_t* pc);
116    virtual void BX(int cc, int Rn);
117    virtual void label(const char* theLabel);
118    virtual void B(int cc, const char* label);
119    virtual void BL(int cc, const char* label);
120
121    virtual uint32_t* pcForLabel(const char* label);
122
123    virtual void ADDR_LDR(int cc, int Rd,
124                int Rn, uint32_t offset = 0);
125    virtual void ADDR_ADD(int cc, int s, int Rd,
126                int Rn, uint32_t Op2);
127    virtual void ADDR_SUB(int cc, int s, int Rd,
128                int Rn, uint32_t Op2);
129    virtual void ADDR_STR (int cc, int Rd,
130                int Rn, uint32_t offset = 0);
131
132    virtual void LDR (int cc, int Rd,
133                int Rn, uint32_t offset = 0);
134    virtual void LDRB(int cc, int Rd,
135                int Rn, uint32_t offset = 0);
136    virtual void STR (int cc, int Rd,
137                int Rn, uint32_t offset = 0);
138    virtual void STRB(int cc, int Rd,
139                int Rn, uint32_t offset = 0);
140    virtual void LDRH (int cc, int Rd,
141                int Rn, uint32_t offset = 0);
142    virtual void LDRSB(int cc, int Rd,
143                int Rn, uint32_t offset = 0);
144    virtual void LDRSH(int cc, int Rd,
145                int Rn, uint32_t offset = 0);
146    virtual void STRH (int cc, int Rd,
147                int Rn, uint32_t offset = 0);
148
149
150    virtual void LDM(int cc, int dir,
151                int Rn, int W, uint32_t reg_list);
152    virtual void STM(int cc, int dir,
153                int Rn, int W, uint32_t reg_list);
154
155    virtual void SWP(int cc, int Rn, int Rd, int Rm);
156    virtual void SWPB(int cc, int Rn, int Rd, int Rm);
157    virtual void SWI(int cc, uint32_t comment);
158
159    virtual void PLD(int Rn, uint32_t offset);
160    virtual void CLZ(int cc, int Rd, int Rm);
161    virtual void QADD(int cc, int Rd, int Rm, int Rn);
162    virtual void QDADD(int cc, int Rd, int Rm, int Rn);
163    virtual void QSUB(int cc, int Rd, int Rm, int Rn);
164    virtual void QDSUB(int cc, int Rd, int Rm, int Rn);
165    virtual void SMUL(int cc, int xy,
166                int Rd, int Rm, int Rs);
167    virtual void SMULW(int cc, int y,
168                int Rd, int Rm, int Rs);
169    virtual void SMLA(int cc, int xy,
170                int Rd, int Rm, int Rs, int Rn);
171    virtual void SMLAL(int cc, int xy,
172                int RdHi, int RdLo, int Rs, int Rm);
173    virtual void SMLAW(int cc, int y,
174                int Rd, int Rm, int Rs, int Rn);
175    virtual void UXTB16(int cc, int Rd, int Rm, int rotate);
176    virtual void UBFX(int cc, int Rd, int Rn, int lsb, int width);
177
178private:
179    ArmToArm64Assembler(const ArmToArm64Assembler& rhs);
180    ArmToArm64Assembler& operator = (const ArmToArm64Assembler& rhs);
181
182    // -----------------------------------------------------------------------
183    // helper functions
184    // -----------------------------------------------------------------------
185
186    void dataTransfer(int operation, int cc, int Rd, int Rn,
187                      uint32_t operand_type, uint32_t size = 32);
188    void dataProcessingCommon(int opcode, int s,
189                      int Rd, int Rn, uint32_t Op2);
190
191    // -----------------------------------------------------------------------
192    // Arm64 instructions
193    // -----------------------------------------------------------------------
194    uint32_t A64_B_COND(uint32_t cc, uint32_t offset);
195    uint32_t A64_RET(uint32_t Rn);
196
197    uint32_t A64_LDRSTR_Wm_SXTW_0(uint32_t operation,
198                                uint32_t size, uint32_t Rt,
199                                uint32_t Rn, uint32_t Rm);
200
201    uint32_t A64_STR_IMM_PreIndex(uint32_t Rt, uint32_t Rn, int32_t simm);
202    uint32_t A64_LDR_IMM_PostIndex(uint32_t Rt,uint32_t Rn, int32_t simm);
203
204    uint32_t A64_ADD_X_Wm_SXTW(uint32_t Rd, uint32_t Rn, uint32_t Rm,
205                               uint32_t amount);
206    uint32_t A64_SUB_X_Wm_SXTW(uint32_t Rd, uint32_t Rn, uint32_t Rm,
207                               uint32_t amount);
208
209    uint32_t A64_ADD_IMM_X(uint32_t Rd, uint32_t Rn,
210                           uint32_t imm, uint32_t shift = 0);
211    uint32_t A64_SUB_IMM_X(uint32_t Rd, uint32_t Rn,
212                           uint32_t imm, uint32_t shift = 0);
213
214    uint32_t A64_ADD_X(uint32_t Rd, uint32_t Rn,
215                       uint32_t Rm, uint32_t shift = 0, uint32_t amount = 0);
216    uint32_t A64_ADD_W(uint32_t Rd, uint32_t Rn, uint32_t Rm,
217                       uint32_t shift = 0, uint32_t amount = 0);
218    uint32_t A64_SUB_W(uint32_t Rd, uint32_t Rn, uint32_t Rm,
219                       uint32_t shift = 0, uint32_t amount = 0,
220                       uint32_t setflag = 0);
221    uint32_t A64_AND_W(uint32_t Rd, uint32_t Rn,
222                       uint32_t Rm, uint32_t shift = 0, uint32_t amount = 0);
223    uint32_t A64_ORR_W(uint32_t Rd, uint32_t Rn,
224                       uint32_t Rm, uint32_t shift = 0, uint32_t amount = 0);
225    uint32_t A64_ORN_W(uint32_t Rd, uint32_t Rn,
226                       uint32_t Rm, uint32_t shift = 0, uint32_t amount = 0);
227
228    uint32_t A64_MOVZ_W(uint32_t Rd, uint32_t imm, uint32_t shift);
229    uint32_t A64_MOVZ_X(uint32_t Rd, uint32_t imm, uint32_t shift);
230    uint32_t A64_MOVK_W(uint32_t Rd, uint32_t imm, uint32_t shift);
231
232    uint32_t A64_SMADDL(uint32_t Rd, uint32_t Rn, uint32_t Rm, uint32_t Ra);
233    uint32_t A64_MADD_W(uint32_t Rd, uint32_t Rn, uint32_t Rm, uint32_t Ra);
234
235    uint32_t A64_SBFM_W(uint32_t Rd, uint32_t Rn,
236                        uint32_t immr, uint32_t imms);
237    uint32_t A64_UBFM_W(uint32_t Rd, uint32_t Rn,
238                        uint32_t immr, uint32_t imms);
239    uint32_t A64_UBFM_X(uint32_t Rd, uint32_t Rn,
240                        uint32_t immr, uint32_t imms);
241
242    uint32_t A64_EXTR_W(uint32_t Rd, uint32_t Rn, uint32_t Rm, uint32_t lsb);
243    uint32_t A64_CSEL_X(uint32_t Rd, uint32_t Rn, uint32_t Rm, uint32_t cond);
244    uint32_t A64_CSEL_W(uint32_t Rd, uint32_t Rn, uint32_t Rm, uint32_t cond);
245
246    uint32_t*       mBase;
247    uint32_t*       mPC;
248    uint32_t*       mPrologPC;
249    int64_t         mDuration;
250    uint32_t        mTmpReg1, mTmpReg2, mTmpReg3, mZeroReg;
251
252    struct branch_target_t {
253        inline branch_target_t() : label(0), pc(0) { }
254        inline branch_target_t(const char* l, uint32_t* p)
255            : label(l), pc(p) { }
256        const char* label;
257        uint32_t*   pc;
258    };
259
260    sp<Assembly>    mAssembly;
261    Vector<branch_target_t>                 mBranchTargets;
262    KeyedVector< const char*, uint32_t* >   mLabels;
263    KeyedVector< uint32_t*, const char* >   mLabelsInverseMapping;
264    KeyedVector< uint32_t*, const char* >   mComments;
265
266    enum operand_type_t
267    {
268        OPERAND_REG = 0x20,
269        OPERAND_IMM,
270        OPERAND_REG_IMM,
271        OPERAND_REG_OFFSET,
272        OPERAND_UNSUPPORTED
273    };
274
275    struct addr_mode_t {
276        int32_t         immediate;
277        bool            writeback;
278        bool            preindex;
279        bool            postindex;
280        int32_t         reg_imm_Rm;
281        int32_t         reg_imm_type;
282        uint32_t        reg_imm_shift;
283        int32_t         reg_offset;
284    } mAddrMode;
285
286};
287
288}; // namespace android
289
290#endif //ANDROID_ARM64ASSEMBLER_H
291