Home | History | Annotate | Download | only in codeflinger
      1 /* libs/pixelflinger/codeflinger/MIPS64Assembler.h
      2 **
      3 ** Copyright 2015, 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 #ifndef ANDROID_MIPS64ASSEMBLER_H
     19 #define ANDROID_MIPS64ASSEMBLER_H
     20 
     21 #include <stdint.h>
     22 #include <sys/types.h>
     23 
     24 #include "utils/KeyedVector.h"
     25 #include "utils/Vector.h"
     26 #include "tinyutils/smartpointer.h"
     27 
     28 #include "ARMAssemblerInterface.h"
     29 #include "MIPSAssembler.h"
     30 #include "CodeCache.h"
     31 
     32 namespace android {
     33 
     34 class MIPS64Assembler;    // forward reference
     35 
     36 // this class mimics ARMAssembler interface
     37 // intent is to translate each ARM instruction to 1 or more MIPS instr
     38 // implementation calls MIPS64Assembler class to generate mips code
     39 class ArmToMips64Assembler : public ARMAssemblerInterface
     40 {
     41 public:
     42                 ArmToMips64Assembler(const sp<Assembly>& assembly,
     43                         char *abuf = 0, int linesz = 0, int instr_count = 0);
     44                 ArmToMips64Assembler(void* assembly);
     45     virtual     ~ArmToMips64Assembler();
     46 
     47     uint32_t*   base() const;
     48     uint32_t*   pc() const;
     49     void        disassemble(const char* name);
     50 
     51     virtual void    reset();
     52 
     53     virtual int     generate(const char* name);
     54     virtual int     getCodegenArch();
     55 
     56     virtual void    prolog();
     57     virtual void    epilog(uint32_t touched);
     58     virtual void    comment(const char* string);
     59     // for testing purposes
     60     void        fix_branches();
     61     void        set_condition(int mode, int R1, int R2);
     62 
     63 
     64     // -----------------------------------------------------------------------
     65     // shifters and addressing modes
     66     // -----------------------------------------------------------------------
     67 
     68     // shifters...
     69     virtual bool        isValidImmediate(uint32_t immed);
     70     virtual int         buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm);
     71 
     72     virtual uint32_t    imm(uint32_t immediate);
     73     virtual uint32_t    reg_imm(int Rm, int type, uint32_t shift);
     74     virtual uint32_t    reg_rrx(int Rm);
     75     virtual uint32_t    reg_reg(int Rm, int type, int Rs);
     76 
     77     // addressing modes...
     78     // LDR(B)/STR(B)/PLD
     79     // (immediate and Rm can be negative, which indicates U=0)
     80     virtual uint32_t    immed12_pre(int32_t immed12, int W=0);
     81     virtual uint32_t    immed12_post(int32_t immed12);
     82     virtual uint32_t    reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0);
     83     virtual uint32_t    reg_scale_post(int Rm, int type=0, uint32_t shift=0);
     84 
     85     // LDRH/LDRSB/LDRSH/STRH
     86     // (immediate and Rm can be negative, which indicates U=0)
     87     virtual uint32_t    immed8_pre(int32_t immed8, int W=0);
     88     virtual uint32_t    immed8_post(int32_t immed8);
     89     virtual uint32_t    reg_pre(int Rm, int W=0);
     90     virtual uint32_t    reg_post(int Rm);
     91 
     92 
     93 
     94 
     95     virtual void    dataProcessing(int opcode, int cc, int s,
     96                                 int Rd, int Rn,
     97                                 uint32_t Op2);
     98     virtual void MLA(int cc, int s,
     99                 int Rd, int Rm, int Rs, int Rn);
    100     virtual void MUL(int cc, int s,
    101                 int Rd, int Rm, int Rs);
    102     virtual void UMULL(int cc, int s,
    103                 int RdLo, int RdHi, int Rm, int Rs);
    104     virtual void UMUAL(int cc, int s,
    105                 int RdLo, int RdHi, int Rm, int Rs);
    106     virtual void SMULL(int cc, int s,
    107                 int RdLo, int RdHi, int Rm, int Rs);
    108     virtual void SMUAL(int cc, int s,
    109                 int RdLo, int RdHi, int Rm, int Rs);
    110 
    111     virtual void B(int cc, uint32_t* pc);
    112     virtual void BL(int cc, uint32_t* pc);
    113     virtual void BX(int cc, int Rn);
    114     virtual void label(const char* theLabel);
    115     virtual void B(int cc, const char* label);
    116     virtual void BL(int cc, const char* label);
    117 
    118     virtual uint32_t* pcForLabel(const char* label);
    119 
    120     virtual void LDR (int cc, int Rd,
    121                 int Rn, uint32_t offset = 0);
    122     virtual void LDRB(int cc, int Rd,
    123                 int Rn, uint32_t offset = 0);
    124     virtual void STR (int cc, int Rd,
    125                 int Rn, uint32_t offset = 0);
    126     virtual void STRB(int cc, int Rd,
    127                 int Rn, uint32_t offset = 0);
    128     virtual void LDRH (int cc, int Rd,
    129                 int Rn, uint32_t offset = 0);
    130     virtual void LDRSB(int cc, int Rd,
    131                 int Rn, uint32_t offset = 0);
    132     virtual void LDRSH(int cc, int Rd,
    133                 int Rn, uint32_t offset = 0);
    134     virtual void STRH (int cc, int Rd,
    135                 int Rn, uint32_t offset = 0);
    136 
    137     virtual void LDM(int cc, int dir,
    138                 int Rn, int W, uint32_t reg_list);
    139     virtual void STM(int cc, int dir,
    140                 int Rn, int W, uint32_t reg_list);
    141 
    142     virtual void SWP(int cc, int Rn, int Rd, int Rm);
    143     virtual void SWPB(int cc, int Rn, int Rd, int Rm);
    144     virtual void SWI(int cc, uint32_t comment);
    145 
    146     virtual void PLD(int Rn, uint32_t offset);
    147     virtual void CLZ(int cc, int Rd, int Rm);
    148     virtual void QADD(int cc, int Rd, int Rm, int Rn);
    149     virtual void QDADD(int cc, int Rd, int Rm, int Rn);
    150     virtual void QSUB(int cc, int Rd, int Rm, int Rn);
    151     virtual void QDSUB(int cc, int Rd, int Rm, int Rn);
    152     virtual void SMUL(int cc, int xy,
    153                 int Rd, int Rm, int Rs);
    154     virtual void SMULW(int cc, int y,
    155                 int Rd, int Rm, int Rs);
    156     virtual void SMLA(int cc, int xy,
    157                 int Rd, int Rm, int Rs, int Rn);
    158     virtual void SMLAL(int cc, int xy,
    159                 int RdHi, int RdLo, int Rs, int Rm);
    160     virtual void SMLAW(int cc, int y,
    161                 int Rd, int Rm, int Rs, int Rn);
    162 
    163     // byte/half word extract...
    164     virtual void UXTB16(int cc, int Rd, int Rm, int rotate);
    165 
    166     // bit manipulation...
    167     virtual void UBFX(int cc, int Rd, int Rn, int lsb, int width);
    168 
    169     // Address loading/storing/manipulation
    170     virtual void ADDR_LDR(int cc, int Rd, int Rn, uint32_t offset = __immed12_pre(0));
    171     virtual void ADDR_STR(int cc, int Rd, int Rn, uint32_t offset = __immed12_pre(0));
    172     virtual void ADDR_ADD(int cc, int s, int Rd, int Rn, uint32_t Op2);
    173     virtual void ADDR_SUB(int cc, int s, int Rd, int Rn, uint32_t Op2);
    174 
    175     // this is some crap to share is MIPS64Assembler class for debug
    176     char *      mArmDisassemblyBuffer;
    177     int         mArmLineLength;
    178     int         mArmInstrCount;
    179 
    180     int         mInum;      // current arm instuction number (0..n)
    181     uint32_t**  mArmPC;     // array: PC for 1st mips instr of
    182                             //      each translated ARM instr
    183 
    184 
    185 private:
    186     ArmToMips64Assembler(const ArmToMips64Assembler& rhs);
    187     ArmToMips64Assembler& operator = (const ArmToMips64Assembler& rhs);
    188 
    189     void init_conditional_labels(void);
    190 
    191     void protectConditionalOperands(int Rd);
    192 
    193     // reg__tmp set to MIPS AT, reg 1
    194     int dataProcAdrModes(int op, int& source, bool sign = false, int reg_tmp = 1);
    195 
    196     sp<Assembly>        mAssembly;
    197     MIPS64Assembler*    mMips;
    198 
    199 
    200     enum misc_constants_t {
    201         ARM_MAX_INSTUCTIONS = 512  // based on ASSEMBLY_SCRATCH_SIZE
    202     };
    203 
    204     enum {
    205         SRC_REG = 0,
    206         SRC_IMM,
    207         SRC_ERROR = -1
    208     };
    209 
    210     enum addr_modes {
    211         // start above the range of legal mips reg #'s (0-31)
    212         AMODE_REG = 0x20,
    213         AMODE_IMM, AMODE_REG_IMM,               // for data processing
    214         AMODE_IMM_12_PRE, AMODE_IMM_12_POST,    // for load/store
    215         AMODE_REG_SCALE_PRE, AMODE_IMM_8_PRE,
    216         AMODE_IMM_8_POST, AMODE_REG_PRE,
    217         AMODE_UNSUPPORTED
    218     };
    219 
    220     struct addr_mode_t {    // address modes for current ARM instruction
    221         int         reg;
    222         int         stype;
    223         uint32_t    value;
    224         bool        writeback;  // writeback the adr reg after modification
    225     } amode;
    226 
    227     enum cond_types {
    228         CMP_COND = 1,
    229         SBIT_COND
    230     };
    231 
    232     struct cond_mode_t {    // conditional-execution info for current ARM instruction
    233         cond_types  type;
    234         int         r1;
    235         int         r2;
    236         int         labelnum;
    237         char        label[100][10];
    238     } cond;
    239 };
    240 
    241 
    242 
    243 
    244 // ----------------------------------------------------------------------------
    245 // ----------------------------------------------------------------------------
    246 // ----------------------------------------------------------------------------
    247 
    248 // This is the basic MIPS64 assembler, which just creates the opcodes in memory.
    249 // All the more complicated work is done in ArmToMips64Assember above.
    250 // Inherits MIPSAssembler class, and overrides only MIPS64r6 specific stuff
    251 
    252 class MIPS64Assembler : public MIPSAssembler
    253 {
    254 public:
    255                 MIPS64Assembler(const sp<Assembly>& assembly, ArmToMips64Assembler *parent);
    256                 MIPS64Assembler(void* assembly, ArmToMips64Assembler *parent);
    257     virtual     ~MIPS64Assembler();
    258 
    259     virtual void        reset();
    260     virtual void        disassemble(const char* name);
    261 
    262     void        fix_branches();
    263 
    264     // ------------------------------------------------------------------------
    265     // MIPS64AssemblerInterface...
    266     // ------------------------------------------------------------------------
    267 
    268 #if 0
    269 #pragma mark -
    270 #pragma mark Arithmetic...
    271 #endif
    272 
    273     void DADDU(int Rd, int Rs, int Rt);
    274     void DADDIU(int Rt, int Rs, int16_t imm);
    275     void DSUBU(int Rd, int Rs, int Rt);
    276     void DSUBIU(int Rt, int Rs, int16_t imm);
    277     virtual void MUL(int Rd, int Rs, int Rt);
    278     void MUH(int Rd, int Rs, int Rt);
    279 
    280 #if 0
    281 #pragma mark -
    282 #pragma mark Logical...
    283 #endif
    284 
    285     virtual void CLO(int Rd, int Rs);
    286     virtual void CLZ(int Rd, int Rs);
    287 
    288 #if 0
    289 #pragma mark -
    290 #pragma mark Load/store...
    291 #endif
    292 
    293     void LD(int Rt, int Rbase, int16_t offset);
    294     void SD(int Rt, int Rbase, int16_t offset);
    295     virtual void LUI(int Rt, int16_t offset);
    296 
    297 #if 0
    298 #pragma mark -
    299 #pragma mark Branch...
    300 #endif
    301 
    302     void JR(int Rs);
    303 
    304 
    305 protected:
    306     ArmToMips64Assembler *mParent;
    307 
    308     // opcode field of all instructions
    309     enum opcode_field {
    310         spec_op, regimm_op, j_op, jal_op,                  // 0x00 - 0x03
    311         beq_op, bne_op, pop06_op, pop07_op,                // 0x04 - 0x07
    312         pop10_op, addiu_op, slti_op, sltiu_op,             // 0x08 - 0x0b
    313         andi_op, ori_op, xori_op, aui_op,                  // 0x0c - 0x0f
    314         cop0_op, cop1_op, cop2_op, rsrv_opc_0,             // 0x10 - 0x13
    315         rsrv_opc_1, rsrv_opc_2, pop26_op, pop27_op,        // 0x14 - 0x17
    316         pop30_op, daddiu_op, rsrv_opc_3, rsrv_opc_4,       // 0x18 - 0x1b
    317         rsrv_opc_5, daui_op, msa_op, spec3_op,             // 0x1c - 0x1f
    318         lb_op, lh_op, rsrv_opc_6, lw_op,                   // 0x20 - 0x23
    319         lbu_op, lhu_op, rsrv_opc_7, lwu_op,                // 0x24 - 0x27
    320         sb_op, sh_op, rsrv_opc_8, sw_op,                   // 0x28 - 0x2b
    321         rsrv_opc_9, rsrv_opc_10, rsrv_opc_11, rsrv_opc_12, // 0x2c - 0x2f
    322         rsrv_opc_13, lwc1_op, bc_op, rsrv_opc_14,          // 0x2c - 0x2f
    323         rsrv_opc_15, ldc1_op, pop66_op, ld_op,             // 0x30 - 0x33
    324         rsrv_opc_16, swc1_op, balc_op, pcrel_op,           // 0x34 - 0x37
    325         rsrv_opc_17, sdc1_op, pop76_op, sd_op              // 0x38 - 0x3b
    326     };
    327 
    328 
    329     // func field for special opcode
    330     enum func_spec_op {
    331         sll_fn, rsrv_spec_0, srl_fn, sra_fn,
    332         sllv_fn, lsa_fn, srlv_fn, srav_fn,
    333         rsrv_spec_1, jalr_fn, rsrv_spec_2, rsrv_spec_3,
    334         syscall_fn, break_fn, sdbbp_fn, sync_fn,
    335         clz_fn, clo_fn, dclz_fn, dclo_fn,
    336         dsllv_fn, dlsa_fn, dsrlv_fn, dsrav_fn,
    337         sop30_fn, sop31_fn, sop32_fn, sop33_fn,
    338         sop34_fn, sop35_fn, sop36_fn, sop37_fn,
    339         add_fn, addu_fn, sub_fn, subu_fn,
    340         and_fn, or_fn, xor_fn, nor_fn,
    341         rsrv_spec_4, rsrv_spec_5, slt_fn, sltu_fn,
    342         dadd_fn, daddu_fn, dsub_fn, dsubu_fn,
    343         tge_fn, tgeu_fn, tlt_fn, tltu_fn,
    344         teq_fn, seleqz_fn, tne_fn, selnez_fn,
    345         dsll_fn, rsrv_spec_6, dsrl_fn, dsra_fn,
    346         dsll32_fn, rsrv_spec_7, dsrl32_fn, dsra32_fn
    347     };
    348 
    349     // func field for spec3 opcode
    350     enum func_spec3_op {
    351         ext_fn, dextm_fn, dextu_fn, dext_fn,
    352         ins_fn, dinsm_fn, dinsu_fn, dins_fn,
    353         cachee_fn = 0x1b, sbe_fn, she_fn, sce_fn, swe_fn,
    354         bshfl_fn, prefe_fn = 0x23, dbshfl_fn, cache_fn, sc_fn, scd_fn,
    355         lbue_fn, lhue_fn, lbe_fn = 0x2c, lhe_fn, lle_fn, lwe_fn,
    356         pref_fn = 0x35, ll_fn, lld_fn, rdhwr_fn = 0x3b
    357     };
    358 
    359     // sa field for spec3 opcodes, with BSHFL function
    360     enum func_spec3_bshfl {
    361         bitswap_fn,
    362         wsbh_fn = 0x02,
    363         dshd_fn = 0x05,
    364         seb_fn = 0x10,
    365         seh_fn = 0x18
    366     };
    367 
    368     // rt field of regimm opcodes.
    369     enum regimm_fn {
    370         bltz_fn, bgez_fn,
    371         dahi_fn = 0x6,
    372         nal_fn = 0x10, bal_fn, bltzall_fn, bgezall_fn,
    373         sigrie_fn = 0x17,
    374         dati_fn = 0x1e, synci_fn
    375     };
    376 
    377     enum muldiv_fn {
    378         mul_fn = 0x02, muh_fn
    379     };
    380 
    381     enum mips_inst_shifts {
    382         OP_SHF       = 26,
    383         JTARGET_SHF  = 0,
    384         RS_SHF       = 21,
    385         RT_SHF       = 16,
    386         RD_SHF       = 11,
    387         RE_SHF       = 6,
    388         SA_SHF       = RE_SHF,  // synonym
    389         IMM_SHF      = 0,
    390         FUNC_SHF     = 0,
    391 
    392         // mask values
    393         MSK_16       = 0xffff,
    394 
    395 
    396         CACHEOP_SHF  = 18,
    397         CACHESEL_SHF = 16,
    398     };
    399 };
    400 
    401 
    402 }; // namespace android
    403 
    404 #endif //ANDROID_MIPS64ASSEMBLER_H
    405