Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkobalicek <kobalicek.petr@gmail.com>2022-04-01 01:41:54 +0300
committerkobalicek <kobalicek.petr@gmail.com>2022-04-01 01:41:54 +0300
commite41f1c0fd736b550328b950b3e42729058d93078 (patch)
tree1ec06ac1db2194615970af30ca307ee15d9be3df
parent7342f7d78d8cd3088bb7b475c3f7ec52f7619980 (diff)
Cleaned up AArch64 RAPass to not shadow variables in _rewrite() (Fixes #359)
-rw-r--r--src/asmjit/arm/a64rapass.cpp80
1 files changed, 41 insertions, 39 deletions
diff --git a/src/asmjit/arm/a64rapass.cpp b/src/asmjit/arm/a64rapass.cpp
index 9e81473..1a4531e 100644
--- a/src/asmjit/arm/a64rapass.cpp
+++ b/src/asmjit/arm/a64rapass.cpp
@@ -713,46 +713,48 @@ ASMJIT_FAVOR_SPEED Error ARMRAPass::_rewrite(BaseNode* first, BaseNode* stop) no
mem.clearRegHome();
mem.addOffsetLo32(offset);
}
+ }
+ }
- // Rewrite `loadAddressOf()` construct.
- if (node->type() == NodeType::kInst) {
- InstNode* inst = node->as<InstNode>();
- if (inst->realId() == Inst::kIdAdr && inst->opCount() == 2) {
- int64_t offset = mem.offset();
- if (!mem.hasBase()) {
- inst->setId(Inst::kIdMov);
- inst->setOp(1, Imm(offset));
- }
- else {
- InstId op = offset < 0 ? Inst::kIdSub : Inst::kIdAdd;
- uint64_t val = offset < 0 ? Support::neg(uint64_t(offset)) : uint64_t(offset);
-
- GpX base = GpX(mem.baseId());
-
- inst->setId(op);
- inst->setOpCount(3);
- inst->setOp(1, base);
- inst->setOp(2, Imm(val));
-
- if (val > 0xFFFu && (val & ~uint64_t(0xFFF000u)) != 0) {
- const Operand_& dst = inst->op(0);
- // Use two operations if the stack address is greater than 4095.
- if (val <= 0xFFFFFFu) {
- cc()->_setCursor(inst->prev());
- cc()->_emitI(op, dst, base, Imm(val & 0xFFFu));
-
- inst->setOp(1, dst);
- inst->setOp(2, Imm(val & 0xFFF000u));
- }
- else {
- cc()->_setCursor(inst->prev());
- cc()->_emitI(Inst::kIdMov, inst->op(0), Imm(val));
-
- inst->setOp(1, base);
- inst->setOp(2, dst);
- }
- }
- }
+ // Rewrite `loadAddressOf()` construct.
+ if (inst->realId() == Inst::kIdAdr && inst->opCount() == 2 && inst->op(1).isMem()) {
+ BaseMem mem = inst->op(1).as<BaseMem>();
+ int64_t offset = mem.offset();
+
+ if (!mem.hasBaseOrIndex()) {
+ inst->setId(Inst::kIdMov);
+ inst->setOp(1, Imm(offset));
+ }
+ else {
+ if (mem.hasIndex())
+ return DebugUtils::errored(kErrorInvalidAddressIndex);
+
+ GpX dst(inst->op(0).as<Gp>().id());
+ GpX base(mem.baseId());
+
+ InstId arithInstId = offset < 0 ? Inst::kIdSub : Inst::kIdAdd;
+ uint64_t absOffset = offset < 0 ? Support::neg(uint64_t(offset)) : uint64_t(offset);
+
+ inst->setId(arithInstId);
+ inst->setOpCount(3);
+ inst->setOp(1, base);
+ inst->setOp(2, Imm(absOffset));
+
+ // Use two operations if the offset cannot be encoded with ADD/SUB.
+ if (absOffset > 0xFFFu && (absOffset & ~uint64_t(0xFFF000u)) != 0) {
+ if (absOffset <= 0xFFFFFFu) {
+ cc()->_setCursor(inst->prev());
+ ASMJIT_PROPAGATE(cc()->emit(arithInstId, dst, base, Imm(absOffset & 0xFFFu)));
+
+ inst->setOp(1, dst);
+ inst->setOp(2, Imm(absOffset & 0xFFF000u));
+ }
+ else {
+ cc()->_setCursor(inst->prev());
+ ASMJIT_PROPAGATE(cc()->emit(Inst::kIdMov, inst->op(0), Imm(absOffset)));
+
+ inst->setOp(1, base);
+ inst->setOp(2, dst);
}
}
}