< prev index next >

src/cpu/aarch32/vm/assembler_aarch32.hpp

Print this page
rev 8069 : 8164652: aarch32: C1 port


 857 
 858 #define INSN(NAME, decode, s_flg)                                                    \
 859   inline void NAME(Register Rd, Register Rn, unsigned imm, Condition cond = C_DFLT) {\
 860     bool status = imm_instr(decode, Rd, Rn, imm, cond, s_flg);                       \
 861     assert(status, "invalid imm");                                                   \
 862   }
 863   INSN(andr, 0b0000, 0);
 864   INSN(eor,  0b0001, 0);
 865   INSN(orr,  0b1100, 0);
 866   INSN(bic,  0b1110, 0);
 867 
 868   INSN(ands, 0b0000, 1);
 869   INSN(eors, 0b0001, 1);
 870   INSN(orrs, 0b1100, 1);
 871   INSN(bics, 0b1110, 1);
 872   //NOTE: arithmetic immediate instructions are defined below to allow dispatch.
 873 #undef INSN
 874  protected:
 875   // Mov data to destination register in the shortest number of instructions
 876   // possible.
 877   void mov_immediate(Register dst, u_int32_t imm32, Condition cond, bool s);
 878   // Mov data to destination register but always emit enough instructions that would
 879   // permit any 32-bit constant to be loaded. (Allow for rewriting later).
 880   void mov_immediate32(Register dst, u_int32_t imm32, Condition cond, bool s);
 881 
 882    void add_sub_imm(int decode, Register Rd, Register Rn, int imm,
 883                    Condition cond, bool s);
 884 
 885  public:
 886 #define INSN(NAME, decode, s_flg)                                                    \
 887   inline void NAME(Register Rd, Register Rn, int imm, Condition cond = C_DFLT) {     \
 888     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 889   }                                                                                  \
 890   inline void NAME(Register Rd, Register Rn, unsigned imm,                           \
 891                    Condition cond = C_DFLT) {                                        \
 892     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 893   }                                                                                  \
 894   inline void NAME(Register Rd, Register Rn, long imm, Condition cond = C_DFLT) {    \
 895     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 896   }                                                                                  \
 897   inline void NAME(Register Rd, Register Rn, unsigned long imm,                      \
 898                    Condition cond = C_DFLT) {                                        \
 899     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 900   }                                                                                  \


1193         // LDR, LDRB, STR, STRB
1194         return uabs(offset) < (1 << 12);
1195       case 0b000:
1196         //LDRD, LDRH, LDRSB, LDRSH, STRH, STRD
1197         return uabs(offset) < (1 << 8);
1198       default:
1199         ShouldNotReachHere();
1200     }
1201     return false;
1202   }
1203 
1204 
1205 
1206 #define INSN_INT(NAME, op, op2, a, b, isload)                                        \
1207   void NAME(Register Rt, address dest, Condition cond = C_DFLT) {                    \
1208     if(encodeable(op, dest)) { /* Plan A */                                          \
1209       long offset = dest - pc();                                                     \
1210       NAME(Rt, Address(r15_pc, offset), cond);                                       \
1211     } else if(isload){ /* Plan B */                                                  \
1212       /* TODO check we don't have to relocate this*/                                 \
1213       mov_immediate(Rt, (u_int32_t)dest, cond, false);                               \
1214       NAME(Rt, Address(Rt, 0), cond);                                                \
1215     } else { /* There is no plan C */                                                \
1216       ShouldNotReachHere();                                                          \
1217     }                                                                                \
1218   }                                                                                  \
1219   void NAME(Register Rt, address dest, relocInfo::relocType rtype,                   \
1220             Condition cond = C_DFLT) {                                               \
1221     guarantee(rtype == relocInfo::internal_word_type,                                \
1222               "only internal_word_type relocs make sense here");                     \
1223     NAME(Rt, InternalAddress(dest), cond);                                           \
1224   }                                                                                  \
1225   void NAME(Register Rt, Label &L, Condition cond = C_DFLT) {                        \
1226     wrap_label(Rt, L, cond, &Assembler::NAME);                                       \
1227   }
1228 
1229 #define INSN(NAME, op, op2, a, b, isload)                                            \
1230   void NAME(Register Rt, const Address &adr, Condition cond = C_DFLT) {              \
1231     load_store_instr(Rt, adr, op, op2, a, b, cond);                                  \
1232   }                                                                                  \
1233   INSN_INT(NAME, op, op2, a, b, isload);


1579 
1580 
1581 // Unconditional Instructions
1582   enum barrier {OSHST = 0b0010, OSH,
1583                 NSHST = 0b0110, NSH,
1584                 ISHST = 0b1010, ISH,
1585                    ST = 0b1110, SY};
1586 
1587   void sync_instr(int decode, enum barrier option) {
1588     starti;
1589     f(0b11110, 31, 27), f(0b1010111, 26, 20), f(0b111111110000, 19, 8);
1590     f(decode, 7, 4), f(option, 3, 0);
1591   }
1592   void clrex() {
1593     sync_instr(0b0001, SY);
1594   }
1595   void dsb(enum barrier option) {
1596     sync_instr(0b0100, option);
1597   }
1598   void dmb(enum barrier option) {
1599     sync_instr(0b0100, option);
1600   }
1601   void bkpt();
1602   void isb() {
1603     sync_instr(0b0110, SY);
1604   }
1605 
1606   // And the relevant instructions for ARMv6.
1607 
1608   // MCR<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}
1609   void mcr(int cpc_dex, int opc1, Register Rt, int cpc_reg_dex1,
1610            int cpc_reg_dex2, int opc2, Condition cond = C_DFLT) {
1611     starti;
1612     f(cond, 31, 28), f(0b1110, 27, 24), f(opc1, 23, 21), f(0, 20);
1613     f(cpc_reg_dex1, 19, 16), rf(Rt, 12), f(cpc_dex, 11, 8);
1614     f(opc2, 7, 5), f(1, 4), f(cpc_reg_dex2, 3, 0);
1615   }
1616 
1617   // These instructions do not read the value of the register passed,
1618   // can be any. Chosen r0.
1619   void cp15dmb(Condition cond = C_DFLT) {




 857 
 858 #define INSN(NAME, decode, s_flg)                                                    \
 859   inline void NAME(Register Rd, Register Rn, unsigned imm, Condition cond = C_DFLT) {\
 860     bool status = imm_instr(decode, Rd, Rn, imm, cond, s_flg);                       \
 861     assert(status, "invalid imm");                                                   \
 862   }
 863   INSN(andr, 0b0000, 0);
 864   INSN(eor,  0b0001, 0);
 865   INSN(orr,  0b1100, 0);
 866   INSN(bic,  0b1110, 0);
 867 
 868   INSN(ands, 0b0000, 1);
 869   INSN(eors, 0b0001, 1);
 870   INSN(orrs, 0b1100, 1);
 871   INSN(bics, 0b1110, 1);
 872   //NOTE: arithmetic immediate instructions are defined below to allow dispatch.
 873 #undef INSN
 874  protected:
 875   // Mov data to destination register in the shortest number of instructions
 876   // possible.
 877   void mov_immediate(Register dst, uint32_t imm32, Condition cond, bool s);
 878   // Mov data to destination register but always emit enough instructions that would
 879   // permit any 32-bit constant to be loaded. (Allow for rewriting later).
 880   void mov_immediate32(Register dst, uint32_t imm32, Condition cond, bool s);
 881 
 882    void add_sub_imm(int decode, Register Rd, Register Rn, int imm,
 883                    Condition cond, bool s);
 884 
 885  public:
 886 #define INSN(NAME, decode, s_flg)                                                    \
 887   inline void NAME(Register Rd, Register Rn, int imm, Condition cond = C_DFLT) {     \
 888     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 889   }                                                                                  \
 890   inline void NAME(Register Rd, Register Rn, unsigned imm,                           \
 891                    Condition cond = C_DFLT) {                                        \
 892     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 893   }                                                                                  \
 894   inline void NAME(Register Rd, Register Rn, long imm, Condition cond = C_DFLT) {    \
 895     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 896   }                                                                                  \
 897   inline void NAME(Register Rd, Register Rn, unsigned long imm,                      \
 898                    Condition cond = C_DFLT) {                                        \
 899     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 900   }                                                                                  \


1193         // LDR, LDRB, STR, STRB
1194         return uabs(offset) < (1 << 12);
1195       case 0b000:
1196         //LDRD, LDRH, LDRSB, LDRSH, STRH, STRD
1197         return uabs(offset) < (1 << 8);
1198       default:
1199         ShouldNotReachHere();
1200     }
1201     return false;
1202   }
1203 
1204 
1205 
1206 #define INSN_INT(NAME, op, op2, a, b, isload)                                        \
1207   void NAME(Register Rt, address dest, Condition cond = C_DFLT) {                    \
1208     if(encodeable(op, dest)) { /* Plan A */                                          \
1209       long offset = dest - pc();                                                     \
1210       NAME(Rt, Address(r15_pc, offset), cond);                                       \
1211     } else if(isload){ /* Plan B */                                                  \
1212       /* TODO check we don't have to relocate this*/                                 \
1213       mov_immediate(Rt, (uint32_t)dest, cond, false);                               \
1214       NAME(Rt, Address(Rt, 0), cond);                                                \
1215     } else { /* There is no plan C */                                                \
1216       ShouldNotReachHere();                                                          \
1217     }                                                                                \
1218   }                                                                                  \
1219   void NAME(Register Rt, address dest, relocInfo::relocType rtype,                   \
1220             Condition cond = C_DFLT) {                                               \
1221     guarantee(rtype == relocInfo::internal_word_type,                                \
1222               "only internal_word_type relocs make sense here");                     \
1223     NAME(Rt, InternalAddress(dest), cond);                                           \
1224   }                                                                                  \
1225   void NAME(Register Rt, Label &L, Condition cond = C_DFLT) {                        \
1226     wrap_label(Rt, L, cond, &Assembler::NAME);                                       \
1227   }
1228 
1229 #define INSN(NAME, op, op2, a, b, isload)                                            \
1230   void NAME(Register Rt, const Address &adr, Condition cond = C_DFLT) {              \
1231     load_store_instr(Rt, adr, op, op2, a, b, cond);                                  \
1232   }                                                                                  \
1233   INSN_INT(NAME, op, op2, a, b, isload);


1579 
1580 
1581 // Unconditional Instructions
1582   enum barrier {OSHST = 0b0010, OSH,
1583                 NSHST = 0b0110, NSH,
1584                 ISHST = 0b1010, ISH,
1585                    ST = 0b1110, SY};
1586 
1587   void sync_instr(int decode, enum barrier option) {
1588     starti;
1589     f(0b11110, 31, 27), f(0b1010111, 26, 20), f(0b111111110000, 19, 8);
1590     f(decode, 7, 4), f(option, 3, 0);
1591   }
1592   void clrex() {
1593     sync_instr(0b0001, SY);
1594   }
1595   void dsb(enum barrier option) {
1596     sync_instr(0b0100, option);
1597   }
1598   void dmb(enum barrier option) {
1599     sync_instr(0b0101, option);
1600   }
1601   void bkpt();
1602   void isb() {
1603     sync_instr(0b0110, SY);
1604   }
1605 
1606   // And the relevant instructions for ARMv6.
1607 
1608   // MCR<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}
1609   void mcr(int cpc_dex, int opc1, Register Rt, int cpc_reg_dex1,
1610            int cpc_reg_dex2, int opc2, Condition cond = C_DFLT) {
1611     starti;
1612     f(cond, 31, 28), f(0b1110, 27, 24), f(opc1, 23, 21), f(0, 20);
1613     f(cpc_reg_dex1, 19, 16), rf(Rt, 12), f(cpc_dex, 11, 8);
1614     f(opc2, 7, 5), f(1, 4), f(cpc_reg_dex2, 3, 0);
1615   }
1616 
1617   // These instructions do not read the value of the register passed,
1618   // can be any. Chosen r0.
1619   void cp15dmb(Condition cond = C_DFLT) {


< prev index next >