[aarch64-port-dev ] Fix overflows in immediate arithemtic
Andrew Haley
aph at redhat.com
Fri Jul 26 04:12:58 PDT 2013
If a constant does not fit in an immediate field, generate some
number of MOV instructions and then perform the operation
Andrew.
# HG changeset patch
# User aph
# Date 1374773485 -3600
# Node ID d9453f3218eefad8a982bb928bbdfcbc727cb2b0
# Parent 42d265e6978f09e0fa9c6d0ec634f1fda662ed8e
Fix overflows in immediate arithemtic
If a constant does not fit in an immediate field, generate some
number of MOV instructions and then perform the operation
diff -r 42d265e6978f -r d9453f3218ee src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Thu Jul 25 18:32:39 2013 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Thu Jul 25 18:31:25 2013 +0100
@@ -1516,6 +1516,21 @@
ldp(rfp, lr, Address(post(sp, 2 * wordSize)));
}
+// If a constant does not fit in an immediate field, generate some
+// number of MOV instructions and then perform the operation
+void MacroAssembler::wrap_add_sub_imm_insn(Register Rd, Register Rn, unsigned imm,
+ add_sub_imm_insn insn1,
+ add_sub_reg_insn insn2) {
+ if (operand_valid_for_add_sub_immediate((int)imm)) {
+ (this->*insn1)(Rd, Rn, imm);
+ } else {
+ assert_different_registers(Rd, Rn);
+ mov(Rd, (uint64_t)imm);
+ (this->*insn2)(Rd, Rn, Rd, LSL, 0);
+ }
+}
+
+
#ifdef ASSERT
static Register spill_registers[] = {
rheapbase,
diff -r 42d265e6978f -r d9453f3218ee src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Thu Jul 25 18:32:39 2013 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Thu Jul 25 18:31:25 2013 +0100
@@ -143,17 +143,6 @@
virtual void notify(int type);
- // Overrides
-
- void subsw(Register Rd, Register Rn, Register Rm,
- enum shift_kind kind, unsigned shift = 0) {
- Assembler::subsw(Rd, Rn, Rm, kind, shift);
- }
-
- void subsw(Register Rd, Register Rn, Register Rm) {
- Assembler::subsw(Rd, Rn, Rm);
- }
-
// aliases defined in AARCH64 spec
@@ -1229,17 +1218,37 @@
void repne_scanw(Register addr, Register value, Register count,
Register scratch);
- // SUBSW with an arbitrary integer operand
- virtual void subsw(Register Rd, Register Rn, unsigned imm) {
- if (operand_valid_for_add_sub_immediate((int)imm)) {
- Assembler::subsw(Rd, Rn, imm);
- } else {
- assert_different_registers(Rd, Rn);
- movw(Rd, imm);
- subsw(Rd, Rn, Rd);
- }
+ typedef void (MacroAssembler::* add_sub_imm_insn)(Register Rd, Register Rn, unsigned imm);
+ typedef void (MacroAssembler::* add_sub_reg_insn)(Register Rd, Register Rn, Register Rm, enum shift_kind kind, unsigned shift);
+
+ // If a constant does not fit in an immediate field, generate some
+ // number of MOV instructions and then perform the operation
+ void wrap_add_sub_imm_insn(Register Rd, Register Rn, unsigned imm,
+ add_sub_imm_insn insn1,
+ add_sub_reg_insn insn2);
+
+#define WRAP(INSN) \
+ void INSN(Register Rd, Register Rn, unsigned imm) { \
+ wrap_add_sub_imm_insn(Rd, Rn, imm, &Assembler::INSN, &Assembler::INSN); \
+ } \
+ \
+ void INSN(Register Rd, Register Rn, Register Rm, \
+ enum shift_kind kind, unsigned shift = 0) { \
+ Assembler::INSN(Rd, Rn, Rm, kind, shift); \
+ } \
+ \
+ void INSN(Register Rd, Register Rn, Register Rm) { \
+ Assembler::INSN(Rd, Rn, Rm); \
+ } \
+ \
+ void INSN(Register Rd, Register Rn, Register Rm, \
+ ext::operation option, int amount = 0) { \
+ Assembler::INSN(Rd, Rn, Rm, option, amount); \
}
+ WRAP(add) WRAP(addw) WRAP(sub) WRAP(subw)
+ WRAP(adds) WRAP(addsw) WRAP(subs) WRAP(subsw)
+
void tableswitch(Register index, jint lowbound, jint highbound,
Label &jumptable, Label &jumptable_end) {
adr(rscratch1, jumptable);
More information about the aarch64-port-dev
mailing list