< prev index next >

src/cpu/aarch64/vm/assembler_aarch64.hpp

Print this page
rev 10278 : 8150394: aarch64: add support for 8.1 LSE CAS instructions
Reviewed-by: duke
Contributed-by: ananth.jasty@caviumnetworks.com, edward.nevill@gmail.com


1152   INSN2(stlrw, word, 0b100, 1);
1153   INSN2(ldarw, word, 0b110, 1);
1154 
1155   // xwords
1156   INSN3(stxr, xword, 0b000, 0);
1157   INSN3(stlxr, xword, 0b000, 1);
1158   INSN4(stxp, xword, 0b001, 0);
1159   INSN4(stlxp, xword, 0b001, 1);
1160   INSN2(ldxr, xword, 0b010, 0);
1161   INSN2(ldaxr, xword, 0b010, 1);
1162   INSN_FOO(ldxp, xword, 0b011, 0);
1163   INSN_FOO(ldaxp, xword, 0b011, 1);
1164   INSN2(stlr, xword, 0b100, 1);
1165   INSN2(ldar, xword, 0b110, 1);
1166 
1167 #undef INSN2
1168 #undef INSN3
1169 #undef INSN4
1170 #undef INSN_FOO
1171 






















































1172   // Load register (literal)
1173 #define INSN(NAME, opc, V)                                              \
1174   void NAME(Register Rt, address dest) {                                \
1175     long offset = (dest - pc()) >> 2;                                   \
1176     starti;                                                             \
1177     f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24),        \
1178       sf(offset, 23, 5);                                                \
1179     rf(Rt, 0);                                                          \
1180   }                                                                     \
1181   void NAME(Register Rt, address dest, relocInfo::relocType rtype) {    \
1182     InstructionMark im(this);                                           \
1183     guarantee(rtype == relocInfo::internal_word_type,                   \
1184               "only internal_word_type relocs make sense here");        \
1185     code_section()->relocate(inst_mark(), InternalAddress(dest).rspec()); \
1186     NAME(Rt, dest);                                                     \
1187   }                                                                     \
1188   void NAME(Register Rt, Label &L) {                                    \
1189     wrap_label(Rt, L, &Assembler::NAME);                                \
1190   }
1191 




1152   INSN2(stlrw, word, 0b100, 1);
1153   INSN2(ldarw, word, 0b110, 1);
1154 
1155   // xwords
1156   INSN3(stxr, xword, 0b000, 0);
1157   INSN3(stlxr, xword, 0b000, 1);
1158   INSN4(stxp, xword, 0b001, 0);
1159   INSN4(stlxp, xword, 0b001, 1);
1160   INSN2(ldxr, xword, 0b010, 0);
1161   INSN2(ldaxr, xword, 0b010, 1);
1162   INSN_FOO(ldxp, xword, 0b011, 0);
1163   INSN_FOO(ldaxp, xword, 0b011, 1);
1164   INSN2(stlr, xword, 0b100, 1);
1165   INSN2(ldar, xword, 0b110, 1);
1166 
1167 #undef INSN2
1168 #undef INSN3
1169 #undef INSN4
1170 #undef INSN_FOO
1171 
1172   // 8.1 Compare and swap extensions
1173   void compare_and_swap(Register Rs, Register Rt, Register Rn,
1174                         enum operand_size sz, int op, int a, int r) {
1175        starti;
1176        f(sz, 31, 30), f(0b001000, 29, 24), f(1, 23), f(a, 22), f(1, 21);
1177        rf(Rs, 16), f(r, 15), f(0b11111, 14, 10), rf(Rn, 5), rf(Rt, 0);
1178   }
1179 
1180   // CAS
1181 #define INSN(NAME, sz, a, r)                                            \
1182   void NAME(Register Rs, Register Rt, Register Rn) {                    \
1183     assert(Rs != Rn && Rs != Rt, "unpredictable instruction");          \
1184     compare_and_swap(Rs, Rt, Rn, sz, 1, a, r);                          \
1185   }
1186   INSN(casb,   byte,     0, 0)
1187   INSN(cash,   halfword, 0, 0)
1188   INSN(casw,   word,     0, 0)
1189   INSN(cas,    xword,    0, 0)
1190   INSN(casab,  byte,     1, 0)
1191   INSN(casah,  halfword, 1, 0)
1192   INSN(casaw,  word,     1, 0)
1193   INSN(casa,   xword,    1, 0)
1194   INSN(caslb,  byte,     0, 1)
1195   INSN(caslh,  halfword, 0, 1)
1196   INSN(caslw,  word,     0, 1)
1197   INSN(casl,   xword,    0, 1)
1198   INSN(casalb, byte,     1, 1)
1199   INSN(casalh, halfword, 1, 1)
1200   INSN(casalw, word,     1, 1)
1201   INSN(casal,  xword,    1, 1)
1202 #undef INSN
1203 
1204   // CASP
1205 #define INSN(NAME, sz, a, r)                                            \
1206   void NAME(Register Rs, Register Rs1,                                  \
1207             Register Rt, Register Rt1, Register Rn) {                   \
1208     assert((Rs->encoding() & 1) == 0 && (Rt->encoding() & 1) == 0 &&    \
1209            Rs->successor() == Rs1 && Rt->successor() == Rt1 &&          \
1210            Rs != Rn && Rs1 != Rn && Rs != Rt, "invalid registers");     \
1211     assert(sz == word || sz == xword, "invalid size");                  \
1212     /* The size bit is in bit 30, not 31 as in ldx/stx above */         \
1213     compare_and_swap(Rs, Rt, Rn,                                        \
1214                      (operand_size)(sz == word ? 0b00:0b01), 0, a, r);  \
1215   }
1216   INSN(caspw,   word,     0, 0)
1217   INSN(casp,    xword,    0, 0)
1218   INSN(caspaw,  word,     1, 0)
1219   INSN(caspa,   xword,    1, 0)
1220   INSN(casplw,  word,     0, 1)
1221   INSN(caspl,   xword,    0, 1)
1222   INSN(caspalw, word,     1, 1)
1223   INSN(caspal,  xword,    1, 1)
1224 #undef INSN
1225 
1226   // Load register (literal)
1227 #define INSN(NAME, opc, V)                                              \
1228   void NAME(Register Rt, address dest) {                                \
1229     long offset = (dest - pc()) >> 2;                                   \
1230     starti;                                                             \
1231     f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24),        \
1232       sf(offset, 23, 5);                                                \
1233     rf(Rt, 0);                                                          \
1234   }                                                                     \
1235   void NAME(Register Rt, address dest, relocInfo::relocType rtype) {    \
1236     InstructionMark im(this);                                           \
1237     guarantee(rtype == relocInfo::internal_word_type,                   \
1238               "only internal_word_type relocs make sense here");        \
1239     code_section()->relocate(inst_mark(), InternalAddress(dest).rspec()); \
1240     NAME(Rt, dest);                                                     \
1241   }                                                                     \
1242   void NAME(Register Rt, Label &L) {                                    \
1243     wrap_label(Rt, L, &Assembler::NAME);                                \
1244   }
1245 


< prev index next >