mirror of
https://github.com/corda/corda.git
synced 2025-01-05 20:54:13 +00:00
make Register a class
This commit is contained in:
parent
02d1a83ad9
commit
998a5168b7
@ -61,13 +61,13 @@ class Architecture {
|
||||
|
||||
virtual const RegisterFile* registerFile() = 0;
|
||||
|
||||
virtual int scratch() = 0;
|
||||
virtual int stack() = 0;
|
||||
virtual int thread() = 0;
|
||||
virtual int returnLow() = 0;
|
||||
virtual int returnHigh() = 0;
|
||||
virtual int virtualCallTarget() = 0;
|
||||
virtual int virtualCallIndex() = 0;
|
||||
virtual Register scratch() = 0;
|
||||
virtual Register stack() = 0;
|
||||
virtual Register thread() = 0;
|
||||
virtual Register returnLow() = 0;
|
||||
virtual Register returnHigh() = 0;
|
||||
virtual Register virtualCallTarget() = 0;
|
||||
virtual Register virtualCallIndex() = 0;
|
||||
|
||||
virtual ir::TargetInfo targetInfo() = 0;
|
||||
|
||||
@ -78,7 +78,7 @@ class Architecture {
|
||||
virtual bool alwaysCondensed(lir::BinaryOperation op) = 0;
|
||||
virtual bool alwaysCondensed(lir::TernaryOperation op) = 0;
|
||||
|
||||
virtual bool reserved(int register_) = 0;
|
||||
virtual bool reserved(Register register_) = 0;
|
||||
|
||||
virtual unsigned frameFootprint(unsigned footprint) = 0;
|
||||
virtual unsigned argumentFootprint(unsigned footprint) = 0;
|
||||
|
@ -77,8 +77,8 @@ class Assembler {
|
||||
virtual void popFrame(unsigned footprint) = 0;
|
||||
virtual void popFrameForTailCall(unsigned footprint,
|
||||
int offset,
|
||||
int returnAddressSurrogate,
|
||||
int framePointerSurrogate) = 0;
|
||||
Register returnAddressSurrogate,
|
||||
Register framePointerSurrogate) = 0;
|
||||
virtual void popFrameAndPopArgumentsAndReturn(unsigned frameFootprint,
|
||||
unsigned argumentFootprint) = 0;
|
||||
virtual void popFrameAndUpdateStackAndReturn(unsigned frameFootprint,
|
||||
|
@ -11,6 +11,8 @@
|
||||
#ifndef AVIAN_CODEGEN_LIR_H
|
||||
#define AVIAN_CODEGEN_LIR_H
|
||||
|
||||
#include <avian/codegen/registers.h>
|
||||
|
||||
namespace avian {
|
||||
namespace codegen {
|
||||
class Promise;
|
||||
@ -151,24 +153,24 @@ class Address : public Operand {
|
||||
|
||||
class RegisterPair : public Operand {
|
||||
public:
|
||||
RegisterPair(int low, int high = NoRegister) : low(low), high(high)
|
||||
RegisterPair(Register low, Register high = NoRegister) : low(low), high(high)
|
||||
{
|
||||
}
|
||||
|
||||
int low;
|
||||
int high;
|
||||
Register low;
|
||||
Register high;
|
||||
};
|
||||
|
||||
class Memory : public Operand {
|
||||
public:
|
||||
Memory(int base, int offset, int index = NoRegister, unsigned scale = 1)
|
||||
Memory(Register base, int offset, Register index = NoRegister, unsigned scale = 1)
|
||||
: base(base), offset(offset), index(index), scale(scale)
|
||||
{
|
||||
}
|
||||
|
||||
int base;
|
||||
Register base;
|
||||
int offset;
|
||||
int index;
|
||||
Register index;
|
||||
unsigned scale;
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,27 @@
|
||||
namespace avian {
|
||||
namespace codegen {
|
||||
|
||||
typedef int Register;
|
||||
class Register {
|
||||
private:
|
||||
int8_t index;
|
||||
public:
|
||||
Register(int8_t index) : index(index) {}
|
||||
Register() : index(0xff) {}
|
||||
|
||||
bool operator == (Register o) const {
|
||||
return index == o.index;
|
||||
}
|
||||
|
||||
bool operator != (Register o) const {
|
||||
return !(*this == o);
|
||||
}
|
||||
|
||||
explicit operator int8_t() const {
|
||||
return index;
|
||||
}
|
||||
|
||||
static Register None;
|
||||
};
|
||||
|
||||
class RegisterMask {
|
||||
private:
|
||||
@ -24,6 +44,7 @@ private:
|
||||
public:
|
||||
RegisterMask(uint64_t mask) : mask(mask) {}
|
||||
RegisterMask() : mask(0) {}
|
||||
RegisterMask(Register reg) : mask(static_cast<uint64_t>(1) << (int8_t)reg) {}
|
||||
|
||||
RegisterMask operator &(RegisterMask o) const {
|
||||
return RegisterMask(mask & o.mask);
|
||||
@ -39,11 +60,15 @@ public:
|
||||
}
|
||||
|
||||
bool contains(Register reg) const {
|
||||
return (mask & (static_cast<uint64_t>(1) << reg)) != 0;
|
||||
return (mask & (static_cast<uint64_t>(1) << (int8_t)reg)) != 0;
|
||||
}
|
||||
|
||||
bool containsExactly(Register reg) const {
|
||||
return mask == (mask & (static_cast<uint64_t>(1) << reg));
|
||||
return mask == (mask & (static_cast<uint64_t>(1) << (int8_t)reg));
|
||||
}
|
||||
|
||||
RegisterMask excluding(Register reg) const {
|
||||
return RegisterMask(mask & ~(static_cast<uint64_t>(1) << (int8_t)reg));
|
||||
}
|
||||
|
||||
explicit operator uint64_t() const {
|
||||
@ -55,6 +80,7 @@ public:
|
||||
}
|
||||
|
||||
static RegisterMask Any;
|
||||
static RegisterMask None;
|
||||
};
|
||||
|
||||
class BoundedRegisterMask {
|
||||
|
@ -2216,18 +2216,18 @@ class Client : public Assembler::Client {
|
||||
Register r = pickRegisterTarget(c, 0, mask, &cost);
|
||||
expect(c, cost < Target::Impossible);
|
||||
save(r);
|
||||
c->registerResources[r].increment(c);
|
||||
c->registerResources[(int8_t)r].increment(c);
|
||||
return r;
|
||||
}
|
||||
|
||||
virtual void releaseTemporary(Register r)
|
||||
{
|
||||
c->registerResources[r].decrement(c);
|
||||
c->registerResources[(int8_t)r].decrement(c);
|
||||
}
|
||||
|
||||
virtual void save(Register r)
|
||||
{
|
||||
RegisterResource* reg = c->registerResources + r;
|
||||
RegisterResource* reg = c->registerResources + (int8_t)r;
|
||||
|
||||
assertT(c, reg->referenceCount == 0);
|
||||
assertT(c, reg->freezeCount == 0);
|
||||
|
@ -399,11 +399,11 @@ class CallEvent : public Event {
|
||||
Register number = c->arch->argumentRegister(index);
|
||||
|
||||
if (DebugReads) {
|
||||
fprintf(stderr, "reg %d arg read %p\n", number, v);
|
||||
fprintf(stderr, "reg %d arg read %p\n", (int8_t)number, v);
|
||||
}
|
||||
|
||||
targetMask = SiteMask::fixedRegisterMask(number);
|
||||
registerMask &= ~(1 << number);
|
||||
registerMask = registerMask.excluding(number);
|
||||
} else {
|
||||
if (index < c->arch->argumentRegisterCount()) {
|
||||
index = c->arch->argumentRegisterCount();
|
||||
@ -587,23 +587,23 @@ class CallEvent : public Event {
|
||||
framePointerSurrogate == 0
|
||||
or framePointerSurrogate->source->type(c) == lir::Operand::Type::RegisterPair);
|
||||
|
||||
int ras;
|
||||
Register ras;
|
||||
if (returnAddressSurrogate) {
|
||||
returnAddressSurrogate->source->freeze(c, returnAddressSurrogate);
|
||||
|
||||
ras = static_cast<RegisterSite*>(returnAddressSurrogate->source)
|
||||
->number;
|
||||
} else {
|
||||
ras = lir::NoRegister;
|
||||
ras = Register::None;
|
||||
}
|
||||
|
||||
int fps;
|
||||
Register fps;
|
||||
if (framePointerSurrogate) {
|
||||
framePointerSurrogate->source->freeze(c, framePointerSurrogate);
|
||||
|
||||
fps = static_cast<RegisterSite*>(framePointerSurrogate->source)->number;
|
||||
} else {
|
||||
fps = lir::NoRegister;
|
||||
fps = Register::None;
|
||||
}
|
||||
|
||||
int offset = static_cast<int>(footprint)
|
||||
@ -1498,14 +1498,14 @@ class MemoryEvent : public Event {
|
||||
|
||||
virtual void compile(Context* c)
|
||||
{
|
||||
int indexRegister;
|
||||
Register indexRegister;
|
||||
int displacement = this->displacement;
|
||||
unsigned scale = this->scale;
|
||||
if (index) {
|
||||
ConstantSite* constant = findConstantSite(c, index);
|
||||
|
||||
if (constant) {
|
||||
indexRegister = lir::NoRegister;
|
||||
indexRegister = Register::None;
|
||||
displacement += (constant->value->value() * scale);
|
||||
scale = 1;
|
||||
} else {
|
||||
@ -1513,14 +1513,14 @@ class MemoryEvent : public Event {
|
||||
indexRegister = static_cast<RegisterSite*>(index->source)->number;
|
||||
}
|
||||
} else {
|
||||
indexRegister = lir::NoRegister;
|
||||
indexRegister = Register::None;
|
||||
}
|
||||
assertT(c, base->source->type(c) == lir::Operand::Type::RegisterPair);
|
||||
int baseRegister = static_cast<RegisterSite*>(base->source)->number;
|
||||
Register baseRegister = static_cast<RegisterSite*>(base->source)->number;
|
||||
|
||||
popRead(c, this, base);
|
||||
if (index) {
|
||||
if (c->targetInfo.pointerSize == 8 and indexRegister != lir::NoRegister) {
|
||||
if (c->targetInfo.pointerSize == 8 and indexRegister != Register::None) {
|
||||
apply(c,
|
||||
lir::Move,
|
||||
4,
|
||||
@ -2035,7 +2035,7 @@ class BoundsCheckEvent : public Event {
|
||||
assertT(c, object->source->type(c) == lir::Operand::Type::RegisterPair);
|
||||
MemorySite length(static_cast<RegisterSite*>(object->source)->number,
|
||||
lengthOffset,
|
||||
lir::NoRegister,
|
||||
Register::None,
|
||||
1);
|
||||
length.acquired = true;
|
||||
|
||||
|
@ -65,13 +65,13 @@ bool pickRegisterTarget(Context* c,
|
||||
CostCalculator* costCalculator)
|
||||
{
|
||||
if (mask.contains(i)) {
|
||||
RegisterResource* r = c->registerResources + i;
|
||||
RegisterResource* r = c->registerResources + (int8_t)i;
|
||||
unsigned myCost
|
||||
= resourceCost(
|
||||
c,
|
||||
v,
|
||||
r,
|
||||
SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, 1 << i, NoFrameIndex),
|
||||
SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, RegisterMask(i), NoFrameIndex),
|
||||
costCalculator) + Target::MinimumRegisterCost;
|
||||
|
||||
if (mask.containsExactly(i)) {
|
||||
@ -91,13 +91,13 @@ Register pickRegisterTarget(Context* c,
|
||||
unsigned* cost,
|
||||
CostCalculator* costCalculator)
|
||||
{
|
||||
Register target = lir::NoRegister;
|
||||
Register target = Register::None;
|
||||
*cost = Target::Impossible;
|
||||
|
||||
if (mask & c->regFile->generalRegisters.mask) {
|
||||
for (Register i = c->regFile->generalRegisters.limit - 1;
|
||||
i >= c->regFile->generalRegisters.start;
|
||||
--i) {
|
||||
(int8_t)i >= c->regFile->generalRegisters.start;
|
||||
i = (int8_t)i - 1) {
|
||||
if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) {
|
||||
return i;
|
||||
}
|
||||
@ -106,8 +106,8 @@ Register pickRegisterTarget(Context* c,
|
||||
|
||||
if (mask & c->regFile->floatRegisters.mask) {
|
||||
for (Register i = c->regFile->floatRegisters.start;
|
||||
i < static_cast<Register>(c->regFile->floatRegisters.limit);
|
||||
++i) {
|
||||
(int8_t)i < c->regFile->floatRegisters.limit;
|
||||
i = (int8_t)i + 1) {
|
||||
if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) {
|
||||
return i;
|
||||
}
|
||||
@ -124,7 +124,7 @@ Target pickRegisterTarget(Context* c,
|
||||
{
|
||||
unsigned cost;
|
||||
Register number = pickRegisterTarget(c, v, mask, &cost, costCalculator);
|
||||
return Target(number, lir::Operand::Type::RegisterPair, cost);
|
||||
return Target(number, cost);
|
||||
}
|
||||
|
||||
unsigned frameCost(Context* c,
|
||||
|
@ -55,11 +55,16 @@ class Target {
|
||||
{
|
||||
}
|
||||
|
||||
Target(Register index, lir::Operand::Type type, unsigned cost)
|
||||
Target(int16_t index, lir::Operand::Type type, unsigned cost)
|
||||
: index(index), type(type), cost(cost)
|
||||
{
|
||||
}
|
||||
|
||||
Target(Register reg, unsigned cost)
|
||||
: index((int8_t)reg), type(lir::Operand::Type::RegisterPair), cost(cost)
|
||||
{
|
||||
}
|
||||
|
||||
int16_t index;
|
||||
lir::Operand::Type type;
|
||||
uint8_t cost;
|
||||
@ -77,14 +82,14 @@ unsigned resourceCost(Context* c,
|
||||
CostCalculator* costCalculator);
|
||||
|
||||
bool pickRegisterTarget(Context* c,
|
||||
int i,
|
||||
Register i,
|
||||
Value* v,
|
||||
RegisterMask mask,
|
||||
int* target,
|
||||
Register* target,
|
||||
unsigned* cost,
|
||||
CostCalculator* costCalculator = 0);
|
||||
|
||||
int pickRegisterTarget(Context* c,
|
||||
Register pickRegisterTarget(Context* c,
|
||||
Value* v,
|
||||
RegisterMask mask,
|
||||
unsigned* cost,
|
||||
|
@ -217,14 +217,14 @@ Site* addressSite(Context* c, Promise* address)
|
||||
return new (c->zone) AddressSite(address);
|
||||
}
|
||||
|
||||
RegisterSite::RegisterSite(RegisterMask mask, int number)
|
||||
RegisterSite::RegisterSite(RegisterMask mask, Register number)
|
||||
: mask_(mask), number(number)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned RegisterSite::toString(Context*, char* buffer, unsigned bufferSize)
|
||||
{
|
||||
if (number != lir::NoRegister) {
|
||||
if (number != Register::None) {
|
||||
return vm::snprintf(buffer, bufferSize, "%p register %d", this, number);
|
||||
} else {
|
||||
return vm::snprintf(
|
||||
@ -234,7 +234,7 @@ unsigned RegisterSite::toString(Context*, char* buffer, unsigned bufferSize)
|
||||
|
||||
unsigned RegisterSite::copyCost(Context* c, Site* s)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
if (s and (this == s
|
||||
or (s->type(c) == lir::Operand::Type::RegisterPair
|
||||
@ -247,7 +247,7 @@ unsigned RegisterSite::copyCost(Context* c, Site* s)
|
||||
|
||||
bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
if ((mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair))) {
|
||||
return mask.registerMask.contains(number);
|
||||
@ -258,7 +258,7 @@ bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask)
|
||||
|
||||
bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
if ((mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair))) {
|
||||
return mask.registerMask.containsExactly(number);
|
||||
@ -269,7 +269,7 @@ bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask)
|
||||
|
||||
bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
if (s->type(c) != lir::Operand::Type::RegisterPair) {
|
||||
return false;
|
||||
@ -278,7 +278,7 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned)
|
||||
RegisterSite* rs = static_cast<RegisterSite*>(s);
|
||||
unsigned size = rs->registerSize(c);
|
||||
if (size > c->targetInfo.pointerSize) {
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
return number == rs->number;
|
||||
} else {
|
||||
RegisterMask mask = c->regFile->generalRegisters.mask;
|
||||
@ -289,8 +289,8 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned)
|
||||
void RegisterSite::acquire(Context* c, Value* v)
|
||||
{
|
||||
Target target;
|
||||
if (number != lir::NoRegister) {
|
||||
target = Target(number, lir::Operand::Type::RegisterPair, 0);
|
||||
if (number != Register::None) {
|
||||
target = Target(number, 0);
|
||||
} else {
|
||||
target = pickRegisterTarget(c, v, mask_);
|
||||
expect(c, target.cost < Target::Impossible);
|
||||
@ -304,30 +304,30 @@ void RegisterSite::acquire(Context* c, Value* v)
|
||||
|
||||
void RegisterSite::release(Context* c, Value* v)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
compiler::release(c, c->registerResources + number, v, this);
|
||||
compiler::release(c, c->registerResources + (int8_t)number, v, this);
|
||||
}
|
||||
|
||||
void RegisterSite::freeze(Context* c, Value* v)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
c->registerResources[number].freeze(c, v);
|
||||
c->registerResources[(int8_t)number].freeze(c, v);
|
||||
}
|
||||
|
||||
void RegisterSite::thaw(Context* c, Value* v)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
c->registerResources[number].thaw(c, v);
|
||||
c->registerResources[(int8_t)number].thaw(c, v);
|
||||
}
|
||||
|
||||
bool RegisterSite::frozen(Context* c UNUSED)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
return c->registerResources[number].freezeCount != 0;
|
||||
return c->registerResources[(int8_t)number].freezeCount != 0;
|
||||
}
|
||||
|
||||
lir::Operand::Type RegisterSite::type(Context*)
|
||||
@ -339,14 +339,14 @@ void RegisterSite::asAssemblerOperand(Context* c UNUSED,
|
||||
Site* high,
|
||||
lir::Operand* result)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
int highNumber;
|
||||
Register highNumber;
|
||||
if (high != this) {
|
||||
highNumber = static_cast<RegisterSite*>(high)->number;
|
||||
assertT(c, highNumber != lir::NoRegister);
|
||||
assertT(c, highNumber != Register::None);
|
||||
} else {
|
||||
highNumber = lir::NoRegister;
|
||||
highNumber = Register::None;
|
||||
}
|
||||
|
||||
new (result) lir::RegisterPair(number, highNumber);
|
||||
@ -356,8 +356,8 @@ Site* RegisterSite::copy(Context* c)
|
||||
{
|
||||
RegisterMask mask;
|
||||
|
||||
if (number != lir::NoRegister) {
|
||||
mask = 1 << number;
|
||||
if (number != Register::None) {
|
||||
mask = RegisterMask(number);
|
||||
} else {
|
||||
mask = mask_;
|
||||
}
|
||||
@ -377,7 +377,7 @@ Site* RegisterSite::copyHigh(Context* c)
|
||||
|
||||
Site* RegisterSite::makeNextWord(Context* c, unsigned)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
assertT(c, c->regFile->generalRegisters.mask.contains(number));
|
||||
|
||||
return freeRegisterSite(c, c->regFile->generalRegisters.mask);
|
||||
@ -390,7 +390,7 @@ SiteMask RegisterSite::mask(Context* c UNUSED)
|
||||
|
||||
SiteMask RegisterSite::nextWordMask(Context* c, unsigned)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
if (registerSize(c) > c->targetInfo.pointerSize) {
|
||||
return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, number, NoFrameIndex);
|
||||
@ -403,7 +403,7 @@ SiteMask RegisterSite::nextWordMask(Context* c, unsigned)
|
||||
|
||||
unsigned RegisterSite::registerSize(Context* c)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
if (c->regFile->floatRegisters.mask.contains(number)) {
|
||||
return c->arch->floatRegisterSize();
|
||||
@ -412,29 +412,29 @@ unsigned RegisterSite::registerSize(Context* c)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned RegisterSite::registerMask(Context* c UNUSED)
|
||||
RegisterMask RegisterSite::registerMask(Context* c UNUSED)
|
||||
{
|
||||
assertT(c, number != lir::NoRegister);
|
||||
assertT(c, number != Register::None);
|
||||
|
||||
return 1 << number;
|
||||
return RegisterMask(number);
|
||||
}
|
||||
|
||||
Site* registerSite(Context* c, int number)
|
||||
Site* registerSite(Context* c, Register number)
|
||||
{
|
||||
assertT(c, number >= 0);
|
||||
assertT(c, number != Register::None);
|
||||
assertT(c,
|
||||
(c->regFile->generalRegisters.mask
|
||||
| c->regFile->floatRegisters.mask).contains(number));
|
||||
|
||||
return new (c->zone) RegisterSite(1 << number, number);
|
||||
return new (c->zone) RegisterSite(RegisterMask(number), number);
|
||||
}
|
||||
|
||||
Site* freeRegisterSite(Context* c, RegisterMask mask)
|
||||
{
|
||||
return new (c->zone) RegisterSite(mask, lir::NoRegister);
|
||||
return new (c->zone) RegisterSite(mask, Register::None);
|
||||
}
|
||||
|
||||
MemorySite::MemorySite(int base, int offset, int index, unsigned scale)
|
||||
MemorySite::MemorySite(Register base, int offset, Register index, unsigned scale)
|
||||
: acquired(false), base(base), offset(offset), index(index), scale(scale)
|
||||
{
|
||||
}
|
||||
@ -468,7 +468,7 @@ bool MemorySite::conflicts(const SiteMask& mask)
|
||||
{
|
||||
return (mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) != 0
|
||||
and (!mask.registerMask.contains(base)
|
||||
or (index != lir::NoRegister
|
||||
or (index != Register::None
|
||||
and !mask.registerMask.contains(index)));
|
||||
}
|
||||
|
||||
@ -479,7 +479,7 @@ bool MemorySite::match(Context* c, const SiteMask& mask)
|
||||
if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) {
|
||||
if (mask.frameIndex >= 0) {
|
||||
if (base == c->arch->stack()) {
|
||||
assertT(c, index == lir::NoRegister);
|
||||
assertT(c, index == Register::None);
|
||||
return static_cast<int>(frameIndexToOffset(c, mask.frameIndex))
|
||||
== offset;
|
||||
} else {
|
||||
@ -499,7 +499,7 @@ bool MemorySite::loneMatch(Context* c, const SiteMask& mask)
|
||||
|
||||
if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) {
|
||||
if (base == c->arch->stack()) {
|
||||
assertT(c, index == lir::NoRegister);
|
||||
assertT(c, index == Register::None);
|
||||
|
||||
if (mask.frameIndex == AnyFrameIndex) {
|
||||
return false;
|
||||
@ -532,13 +532,13 @@ bool MemorySite::matchNextWord(Context* c, Site* s, unsigned index)
|
||||
|
||||
void MemorySite::acquire(Context* c, Value* v)
|
||||
{
|
||||
c->registerResources[base].increment(c);
|
||||
if (index != lir::NoRegister) {
|
||||
c->registerResources[index].increment(c);
|
||||
c->registerResources[(int8_t)base].increment(c);
|
||||
if (index != Register::None) {
|
||||
c->registerResources[(int8_t)index].increment(c);
|
||||
}
|
||||
|
||||
if (base == c->arch->stack()) {
|
||||
assertT(c, index == lir::NoRegister);
|
||||
assertT(c, index == Register::None);
|
||||
assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
|
||||
|
||||
compiler::acquire(
|
||||
@ -551,16 +551,16 @@ void MemorySite::acquire(Context* c, Value* v)
|
||||
void MemorySite::release(Context* c, Value* v)
|
||||
{
|
||||
if (base == c->arch->stack()) {
|
||||
assertT(c, index == lir::NoRegister);
|
||||
assertT(c, index == Register::None);
|
||||
assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
|
||||
|
||||
compiler::release(
|
||||
c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
|
||||
}
|
||||
|
||||
c->registerResources[base].decrement(c);
|
||||
if (index != lir::NoRegister) {
|
||||
c->registerResources[index].decrement(c);
|
||||
c->registerResources[(int8_t)base].decrement(c);
|
||||
if (index != Register::None) {
|
||||
c->registerResources[(int8_t)index].decrement(c);
|
||||
}
|
||||
|
||||
acquired = false;
|
||||
@ -571,9 +571,9 @@ void MemorySite::freeze(Context* c, Value* v)
|
||||
if (base == c->arch->stack()) {
|
||||
c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v);
|
||||
} else {
|
||||
c->registerResources[base].increment(c);
|
||||
if (index != lir::NoRegister) {
|
||||
c->registerResources[index].increment(c);
|
||||
c->registerResources[(int8_t)base].increment(c);
|
||||
if (index != Register::None) {
|
||||
c->registerResources[(int8_t)index].increment(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -583,9 +583,9 @@ void MemorySite::thaw(Context* c, Value* v)
|
||||
if (base == c->arch->stack()) {
|
||||
c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v);
|
||||
} else {
|
||||
c->registerResources[base].decrement(c);
|
||||
if (index != lir::NoRegister) {
|
||||
c->registerResources[index].decrement(c);
|
||||
c->registerResources[(int8_t)base].decrement(c);
|
||||
if (index != Register::None) {
|
||||
c->registerResources[(int8_t)index].decrement(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -668,7 +668,7 @@ SiteMask MemorySite::nextWordMask(Context* c, unsigned index)
|
||||
{
|
||||
int frameIndex;
|
||||
if (base == c->arch->stack()) {
|
||||
assertT(c, this->index == lir::NoRegister);
|
||||
assertT(c, this->index == Register::None);
|
||||
frameIndex = static_cast<int>(offsetToFrameIndex(c, offset))
|
||||
+ ((index == 1) xor c->arch->bigEndian() ? 1 : -1);
|
||||
} else {
|
||||
@ -683,9 +683,9 @@ bool MemorySite::isVolatile(Context* c)
|
||||
}
|
||||
|
||||
MemorySite* memorySite(Context* c,
|
||||
int base,
|
||||
Register base,
|
||||
int offset,
|
||||
int index,
|
||||
Register index,
|
||||
unsigned scale)
|
||||
{
|
||||
return new (c->zone) MemorySite(base, offset, index, scale);
|
||||
@ -697,7 +697,7 @@ MemorySite* frameSite(Context* c, int frameIndex)
|
||||
return memorySite(c,
|
||||
c->arch->stack(),
|
||||
frameIndexToOffset(c, frameIndex),
|
||||
lir::NoRegister,
|
||||
Register::None,
|
||||
0);
|
||||
}
|
||||
|
||||
|
@ -41,9 +41,9 @@ class SiteMask {
|
||||
|
||||
SiteMask intersectionWith(const SiteMask& b);
|
||||
|
||||
static SiteMask fixedRegisterMask(int number)
|
||||
static SiteMask fixedRegisterMask(Register number)
|
||||
{
|
||||
return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, 1 << number, NoFrameIndex);
|
||||
return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, 1 << (int8_t)number, NoFrameIndex);
|
||||
}
|
||||
|
||||
static SiteMask lowPart(const OperandMask& mask)
|
||||
@ -121,7 +121,7 @@ class Site {
|
||||
|
||||
virtual unsigned registerSize(Context*);
|
||||
|
||||
virtual unsigned registerMask(Context*)
|
||||
virtual RegisterMask registerMask(Context*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -251,7 +251,7 @@ Site* addressSite(Context* c, Promise* address);
|
||||
|
||||
class RegisterSite : public Site {
|
||||
public:
|
||||
RegisterSite(RegisterMask mask, int number);
|
||||
RegisterSite(RegisterMask mask, Register number);
|
||||
|
||||
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize);
|
||||
|
||||
@ -293,18 +293,18 @@ class RegisterSite : public Site {
|
||||
|
||||
virtual unsigned registerSize(Context* c);
|
||||
|
||||
virtual unsigned registerMask(Context* c UNUSED);
|
||||
virtual RegisterMask registerMask(Context* c UNUSED);
|
||||
|
||||
RegisterMask mask_;
|
||||
int number;
|
||||
Register number;
|
||||
};
|
||||
|
||||
Site* registerSite(Context* c, int number);
|
||||
Site* registerSite(Context* c, Register number);
|
||||
Site* freeRegisterSite(Context* c, RegisterMask mask);
|
||||
|
||||
class MemorySite : public Site {
|
||||
public:
|
||||
MemorySite(int base, int offset, int index, unsigned scale);
|
||||
MemorySite(Register base, int offset, Register index, unsigned scale);
|
||||
|
||||
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize);
|
||||
|
||||
@ -351,16 +351,16 @@ class MemorySite : public Site {
|
||||
virtual bool isVolatile(Context* c);
|
||||
|
||||
bool acquired;
|
||||
int base;
|
||||
Register base;
|
||||
int offset;
|
||||
int index;
|
||||
Register index;
|
||||
unsigned scale;
|
||||
};
|
||||
|
||||
MemorySite* memorySite(Context* c,
|
||||
int base,
|
||||
Register base,
|
||||
int offset = 0,
|
||||
int index = lir::NoRegister,
|
||||
Register index = Register::None,
|
||||
unsigned scale = 1);
|
||||
MemorySite* frameSite(Context* c, int frameIndex);
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
namespace avian {
|
||||
namespace codegen {
|
||||
|
||||
Register Register::None(-1);
|
||||
|
||||
unsigned BoundedRegisterMask::maskStart(RegisterMask mask)
|
||||
{
|
||||
for (int i = 0; i <= 31; ++i) {
|
||||
|
@ -164,37 +164,37 @@ class MyArchitecture : public Architecture {
|
||||
: &MyRegisterFileWithoutFloats;
|
||||
}
|
||||
|
||||
virtual int scratch()
|
||||
virtual Register scratch()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
virtual int stack()
|
||||
virtual Register stack()
|
||||
{
|
||||
return StackRegister;
|
||||
}
|
||||
|
||||
virtual int thread()
|
||||
virtual Register thread()
|
||||
{
|
||||
return ThreadRegister;
|
||||
}
|
||||
|
||||
virtual int returnLow()
|
||||
virtual Register returnLow()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int returnHigh()
|
||||
virtual Register returnHigh()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual int virtualCallTarget()
|
||||
virtual Register virtualCallTarget()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
virtual int virtualCallIndex()
|
||||
virtual Register virtualCallIndex()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
@ -214,9 +214,9 @@ class MyArchitecture : public Architecture {
|
||||
return 0x1FFFFFF;
|
||||
}
|
||||
|
||||
virtual bool reserved(int register_)
|
||||
virtual bool reserved(Register register_)
|
||||
{
|
||||
switch (register_) {
|
||||
switch ((int8_t)register_) {
|
||||
case LinkRegister:
|
||||
case StackRegister:
|
||||
case ThreadRegister:
|
||||
@ -261,7 +261,7 @@ class MyArchitecture : public Architecture {
|
||||
return 4;
|
||||
}
|
||||
|
||||
virtual int argumentRegister(unsigned index)
|
||||
virtual Register argumentRegister(unsigned index)
|
||||
{
|
||||
assertT(&con, index < argumentRegisterCount());
|
||||
|
||||
@ -789,10 +789,10 @@ class MyAssembler : public Assembler {
|
||||
|
||||
virtual void popFrameForTailCall(unsigned footprint,
|
||||
int offset,
|
||||
int returnAddressSurrogate,
|
||||
int framePointerSurrogate UNUSED)
|
||||
Register returnAddressSurrogate,
|
||||
Register framePointerSurrogate UNUSED)
|
||||
{
|
||||
assertT(&con, framePointerSurrogate == lir::NoRegister);
|
||||
assertT(&con, framePointerSurrogate == Register::None);
|
||||
|
||||
if (TailCalls) {
|
||||
if (offset) {
|
||||
@ -813,7 +813,7 @@ class MyAssembler : public Assembler {
|
||||
lir::Constant footprintConstant(&footprintPromise);
|
||||
addC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack);
|
||||
|
||||
if (returnAddressSurrogate != lir::NoRegister) {
|
||||
if (returnAddressSurrogate != Register::None) {
|
||||
assertT(&con, offset > 0);
|
||||
|
||||
lir::RegisterPair ras(returnAddressSurrogate);
|
||||
|
@ -46,34 +46,34 @@ enum CONDITION {
|
||||
enum SHIFTOP { LSL, LSR, ASR, ROR };
|
||||
// INSTRUCTION FORMATS
|
||||
inline int
|
||||
DATA(int cond, int opcode, int S, int Rn, int Rd, int shift, int Sh, int Rm)
|
||||
DATA(int cond, int opcode, int S, Register Rn, Register Rd, int shift, int Sh, Register Rm)
|
||||
{
|
||||
return cond << 28 | opcode << 21 | S << 20 | Rn << 16 | Rd << 12 | shift << 7
|
||||
| Sh << 5 | Rm;
|
||||
return cond << 28 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | shift << 7
|
||||
| Sh << 5 | (int8_t)Rm;
|
||||
}
|
||||
inline int
|
||||
DATAS(int cond, int opcode, int S, int Rn, int Rd, int Rs, int Sh, int Rm)
|
||||
DATAS(int cond, int opcode, int S, Register Rn, Register Rd, Register Rs, int Sh, Register Rm)
|
||||
{
|
||||
return cond << 28 | opcode << 21 | S << 20 | Rn << 16 | Rd << 12 | Rs << 8
|
||||
| Sh << 5 | 1 << 4 | Rm;
|
||||
return cond << 28 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | (int8_t)Rs << 8
|
||||
| Sh << 5 | 1 << 4 | (int8_t)Rm;
|
||||
}
|
||||
inline int DATAI(int cond, int opcode, int S, int Rn, int Rd, int rot, int imm)
|
||||
inline int DATAI(int cond, int opcode, int S, Register Rn, Register Rd, int rot, int imm)
|
||||
{
|
||||
return cond << 28 | 1 << 25 | opcode << 21 | S << 20 | Rn << 16 | Rd << 12
|
||||
return cond << 28 | 1 << 25 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12
|
||||
| rot << 8 | (imm & 0xff);
|
||||
}
|
||||
inline int BRANCH(int cond, int L, int offset)
|
||||
{
|
||||
return cond << 28 | 5 << 25 | L << 24 | (offset & 0xffffff);
|
||||
}
|
||||
inline int BRANCHX(int cond, int L, int Rm)
|
||||
inline int BRANCHX(int cond, int L, Register Rm)
|
||||
{
|
||||
return cond << 28 | 0x4bffc << 6 | L << 5 | 1 << 4 | Rm;
|
||||
return cond << 28 | 0x4bffc << 6 | L << 5 | 1 << 4 | (int8_t)Rm;
|
||||
}
|
||||
inline int MULTIPLY(int cond, int mul, int S, int Rd, int Rn, int Rs, int Rm)
|
||||
inline int MULTIPLY(int cond, int mul, int S, Register Rd, Register Rn, Register Rs, Register Rm)
|
||||
{
|
||||
return cond << 28 | mul << 21 | S << 20 | Rd << 16 | Rn << 12 | Rs << 8
|
||||
| 9 << 4 | Rm;
|
||||
return cond << 28 | mul << 21 | S << 20 | (int8_t)Rd << 16 | (int8_t)Rn << 12 | (int8_t)Rs << 8
|
||||
| 9 << 4 | (int8_t)Rm;
|
||||
}
|
||||
inline int XFER(int cond,
|
||||
int P,
|
||||
@ -81,14 +81,14 @@ inline int XFER(int cond,
|
||||
int B,
|
||||
int W,
|
||||
int L,
|
||||
int Rn,
|
||||
int Rd,
|
||||
Register Rn,
|
||||
Register Rd,
|
||||
int shift,
|
||||
int Sh,
|
||||
int Rm)
|
||||
Register Rm)
|
||||
{
|
||||
return cond << 28 | 3 << 25 | P << 24 | U << 23 | B << 22 | W << 21 | L << 20
|
||||
| Rn << 16 | Rd << 12 | shift << 7 | Sh << 5 | Rm;
|
||||
| (int8_t)Rn << 16 | (int8_t)Rd << 12 | shift << 7 | Sh << 5 | (int8_t)Rm;
|
||||
}
|
||||
inline int XFERI(int cond,
|
||||
int P,
|
||||
@ -96,53 +96,53 @@ inline int XFERI(int cond,
|
||||
int B,
|
||||
int W,
|
||||
int L,
|
||||
int Rn,
|
||||
int Rd,
|
||||
Register Rn,
|
||||
Register Rd,
|
||||
int offset)
|
||||
{
|
||||
return cond << 28 | 2 << 25 | P << 24 | U << 23 | B << 22 | W << 21 | L << 20
|
||||
| Rn << 16 | Rd << 12 | (offset & 0xfff);
|
||||
| (int8_t)Rn << 16 | (int8_t)Rd << 12 | (offset & 0xfff);
|
||||
}
|
||||
inline int XFER2(int cond,
|
||||
int P,
|
||||
int U,
|
||||
int W,
|
||||
int L,
|
||||
int Rn,
|
||||
int Rd,
|
||||
Register Rn,
|
||||
Register Rd,
|
||||
int S,
|
||||
int H,
|
||||
int Rm)
|
||||
Register Rm)
|
||||
{
|
||||
return cond << 28 | P << 24 | U << 23 | W << 21 | L << 20 | Rn << 16
|
||||
| Rd << 12 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | Rm;
|
||||
return cond << 28 | P << 24 | U << 23 | W << 21 | L << 20 | (int8_t)Rn << 16
|
||||
| (int8_t)Rd << 12 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | (int8_t)Rm;
|
||||
}
|
||||
inline int XFER2I(int cond,
|
||||
int P,
|
||||
int U,
|
||||
int W,
|
||||
int L,
|
||||
int Rn,
|
||||
int Rd,
|
||||
Register Rn,
|
||||
Register Rd,
|
||||
int offsetH,
|
||||
int S,
|
||||
int H,
|
||||
int offsetL)
|
||||
{
|
||||
return cond << 28 | P << 24 | U << 23 | 1 << 22 | W << 21 | L << 20 | Rn << 16
|
||||
| Rd << 12 | offsetH << 8 | 1 << 7 | S << 6 | H << 5 | 1 << 4
|
||||
return cond << 28 | P << 24 | U << 23 | 1 << 22 | W << 21 | L << 20 | (int8_t)Rn << 16
|
||||
| (int8_t)Rd << 12 | offsetH << 8 | 1 << 7 | S << 6 | H << 5 | 1 << 4
|
||||
| (offsetL & 0xf);
|
||||
}
|
||||
inline int COOP(int cond,
|
||||
int opcode_1,
|
||||
int CRn,
|
||||
int CRd,
|
||||
Register CRn,
|
||||
Register CRd,
|
||||
int cp_num,
|
||||
int opcode_2,
|
||||
int CRm)
|
||||
Register CRm)
|
||||
{
|
||||
return cond << 28 | 0xe << 24 | opcode_1 << 20 | CRn << 16 | CRd << 12
|
||||
| cp_num << 8 | opcode_2 << 5 | CRm;
|
||||
return cond << 28 | 0xe << 24 | opcode_1 << 20 | (int8_t)CRn << 16 | (int8_t)CRd << 12
|
||||
| cp_num << 8 | opcode_2 << 5 | (int8_t)CRm;
|
||||
}
|
||||
inline int COXFER(int cond,
|
||||
int P,
|
||||
@ -150,31 +150,31 @@ inline int COXFER(int cond,
|
||||
int N,
|
||||
int W,
|
||||
int L,
|
||||
int Rn,
|
||||
int CRd,
|
||||
Register Rn,
|
||||
Register CRd,
|
||||
int cp_num,
|
||||
int offset) // offset is in words, not bytes
|
||||
{
|
||||
return cond << 28 | 0x6 << 25 | P << 24 | U << 23 | N << 22 | W << 21
|
||||
| L << 20 | Rn << 16 | CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2;
|
||||
| L << 20 | (int8_t)Rn << 16 | (int8_t)CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2;
|
||||
}
|
||||
inline int COREG(int cond,
|
||||
int opcode_1,
|
||||
int L,
|
||||
int CRn,
|
||||
int Rd,
|
||||
Register CRn,
|
||||
Register Rd,
|
||||
int cp_num,
|
||||
int opcode_2,
|
||||
int CRm)
|
||||
Register CRm)
|
||||
{
|
||||
return cond << 28 | 0xe << 24 | opcode_1 << 21 | L << 20 | CRn << 16
|
||||
| Rd << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | CRm;
|
||||
return cond << 28 | 0xe << 24 | opcode_1 << 21 | L << 20 | (int8_t)CRn << 16
|
||||
| (int8_t)Rd << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | (int8_t)CRm;
|
||||
}
|
||||
inline int
|
||||
COREG2(int cond, int L, int Rn, int Rd, int cp_num, int opcode, int CRm)
|
||||
COREG2(int cond, int L, Register Rn, Register Rd, int cp_num, int opcode, Register CRm)
|
||||
{
|
||||
return cond << 28 | 0xc4 << 20 | L << 20 | Rn << 16 | Rd << 12 | cp_num << 8
|
||||
| opcode << 4 | CRm;
|
||||
return cond << 28 | 0xc4 << 20 | L << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | cp_num << 8
|
||||
| opcode << 4 | (int8_t)CRm;
|
||||
}
|
||||
// FIELD CALCULATORS
|
||||
inline int calcU(int imm)
|
||||
@ -191,143 +191,143 @@ inline int bl(int offset)
|
||||
{
|
||||
return BRANCH(AL, 1, offset);
|
||||
}
|
||||
inline int bx(int Rm)
|
||||
inline int bx(Register Rm)
|
||||
{
|
||||
return BRANCHX(AL, 0, Rm);
|
||||
}
|
||||
inline int blx(int Rm)
|
||||
inline int blx(Register Rm)
|
||||
{
|
||||
return BRANCHX(AL, 1, Rm);
|
||||
}
|
||||
inline int and_(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
|
||||
inline int and_(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0)
|
||||
{
|
||||
return DATA(AL, 0x0, 0, Rn, Rd, shift, Sh, Rm);
|
||||
}
|
||||
inline int eor(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
|
||||
inline int eor(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0)
|
||||
{
|
||||
return DATA(AL, 0x1, 0, Rn, Rd, shift, Sh, Rm);
|
||||
}
|
||||
inline int rsb(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
|
||||
inline int rsb(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0)
|
||||
{
|
||||
return DATA(AL, 0x3, 0, Rn, Rd, shift, Sh, Rm);
|
||||
}
|
||||
inline int add(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
|
||||
inline int add(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0)
|
||||
{
|
||||
return DATA(AL, 0x4, 0, Rn, Rd, shift, Sh, Rm);
|
||||
}
|
||||
inline int adc(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
|
||||
inline int adc(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0)
|
||||
{
|
||||
return DATA(AL, 0x5, 0, Rn, Rd, shift, Sh, Rm);
|
||||
}
|
||||
inline int rsc(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
|
||||
inline int rsc(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0)
|
||||
{
|
||||
return DATA(AL, 0x7, 0, Rn, Rd, shift, Sh, Rm);
|
||||
}
|
||||
inline int cmp(int Rn, int Rm, int Sh = 0, int shift = 0)
|
||||
inline int cmp(Register Rn, Register Rm, int Sh = 0, int shift = 0)
|
||||
{
|
||||
return DATA(AL, 0xa, 1, Rn, 0, shift, Sh, Rm);
|
||||
}
|
||||
inline int orr(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
|
||||
inline int orr(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0)
|
||||
{
|
||||
return DATA(AL, 0xc, 0, Rn, Rd, shift, Sh, Rm);
|
||||
}
|
||||
inline int mov(int Rd, int Rm, int Sh = 0, int shift = 0)
|
||||
inline int mov(Register Rd, Register Rm, int Sh = 0, int shift = 0)
|
||||
{
|
||||
return DATA(AL, 0xd, 0, 0, Rd, shift, Sh, Rm);
|
||||
}
|
||||
inline int mvn(int Rd, int Rm, int Sh = 0, int shift = 0)
|
||||
inline int mvn(Register Rd, Register Rm, int Sh = 0, int shift = 0)
|
||||
{
|
||||
return DATA(AL, 0xf, 0, 0, Rd, shift, Sh, Rm);
|
||||
}
|
||||
inline int andi(int Rd, int Rn, int imm, int rot = 0)
|
||||
inline int andi(Register Rd, Register Rn, int imm, int rot = 0)
|
||||
{
|
||||
return DATAI(AL, 0x0, 0, Rn, Rd, rot, imm);
|
||||
}
|
||||
inline int subi(int Rd, int Rn, int imm, int rot = 0)
|
||||
inline int subi(Register Rd, Register Rn, int imm, int rot = 0)
|
||||
{
|
||||
return DATAI(AL, 0x2, 0, Rn, Rd, rot, imm);
|
||||
}
|
||||
inline int rsbi(int Rd, int Rn, int imm, int rot = 0)
|
||||
inline int rsbi(Register Rd, Register Rn, int imm, int rot = 0)
|
||||
{
|
||||
return DATAI(AL, 0x3, 0, Rn, Rd, rot, imm);
|
||||
}
|
||||
inline int addi(int Rd, int Rn, int imm, int rot = 0)
|
||||
inline int addi(Register Rd, Register Rn, int imm, int rot = 0)
|
||||
{
|
||||
return DATAI(AL, 0x4, 0, Rn, Rd, rot, imm);
|
||||
}
|
||||
inline int adci(int Rd, int Rn, int imm, int rot = 0)
|
||||
inline int adci(Register Rd, Register Rn, int imm, int rot = 0)
|
||||
{
|
||||
return DATAI(AL, 0x5, 0, Rn, Rd, rot, imm);
|
||||
}
|
||||
inline int bici(int Rd, int Rn, int imm, int rot = 0)
|
||||
inline int bici(Register Rd, Register Rn, int imm, int rot = 0)
|
||||
{
|
||||
return DATAI(AL, 0xe, 0, Rn, Rd, rot, imm);
|
||||
}
|
||||
inline int cmpi(int Rn, int imm, int rot = 0)
|
||||
inline int cmpi(Register Rn, int imm, int rot = 0)
|
||||
{
|
||||
return DATAI(AL, 0xa, 1, Rn, 0, rot, imm);
|
||||
}
|
||||
inline int movi(int Rd, int imm, int rot = 0)
|
||||
inline int movi(Register Rd, int imm, int rot = 0)
|
||||
{
|
||||
return DATAI(AL, 0xd, 0, 0, Rd, rot, imm);
|
||||
}
|
||||
inline int orrsh(int Rd, int Rn, int Rm, int Rs, int Sh)
|
||||
inline int orrsh(Register Rd, Register Rn, Register Rm, Register Rs, int Sh)
|
||||
{
|
||||
return DATAS(AL, 0xc, 0, Rn, Rd, Rs, Sh, Rm);
|
||||
}
|
||||
inline int movsh(int Rd, int Rm, int Rs, int Sh)
|
||||
inline int movsh(Register Rd, Register Rm, Register Rs, int Sh)
|
||||
{
|
||||
return DATAS(AL, 0xd, 0, 0, Rd, Rs, Sh, Rm);
|
||||
}
|
||||
inline int mul(int Rd, int Rm, int Rs)
|
||||
inline int mul(Register Rd, Register Rm, Register Rs)
|
||||
{
|
||||
return MULTIPLY(AL, 0, 0, Rd, 0, Rs, Rm);
|
||||
}
|
||||
inline int mla(int Rd, int Rm, int Rs, int Rn)
|
||||
inline int mla(Register Rd, Register Rm, Register Rs, Register Rn)
|
||||
{
|
||||
return MULTIPLY(AL, 1, 0, Rd, Rn, Rs, Rm);
|
||||
}
|
||||
inline int umull(int RdLo, int RdHi, int Rm, int Rs)
|
||||
inline int umull(Register RdLo, Register RdHi, Register Rm, Register Rs)
|
||||
{
|
||||
return MULTIPLY(AL, 4, 0, RdHi, RdLo, Rs, Rm);
|
||||
}
|
||||
inline int ldr(int Rd, int Rn, int Rm, int W = 0)
|
||||
inline int ldr(Register Rd, Register Rn, Register Rm, int W = 0)
|
||||
{
|
||||
return XFER(AL, 1, 1, 0, W, 1, Rn, Rd, 0, 0, Rm);
|
||||
}
|
||||
inline int ldri(int Rd, int Rn, int imm, int W = 0)
|
||||
inline int ldri(Register Rd, Register Rn, int imm, int W = 0)
|
||||
{
|
||||
return XFERI(AL, 1, calcU(imm), 0, W, 1, Rn, Rd, abs(imm));
|
||||
}
|
||||
inline int ldrb(int Rd, int Rn, int Rm)
|
||||
inline int ldrb(Register Rd, Register Rn, Register Rm)
|
||||
{
|
||||
return XFER(AL, 1, 1, 1, 0, 1, Rn, Rd, 0, 0, Rm);
|
||||
}
|
||||
inline int ldrbi(int Rd, int Rn, int imm)
|
||||
inline int ldrbi(Register Rd, Register Rn, int imm)
|
||||
{
|
||||
return XFERI(AL, 1, calcU(imm), 1, 0, 1, Rn, Rd, abs(imm));
|
||||
}
|
||||
inline int str(int Rd, int Rn, int Rm, int W = 0)
|
||||
inline int str(Register Rd, Register Rn, Register Rm, int W = 0)
|
||||
{
|
||||
return XFER(AL, 1, 1, 0, W, 0, Rn, Rd, 0, 0, Rm);
|
||||
}
|
||||
inline int stri(int Rd, int Rn, int imm, int W = 0)
|
||||
inline int stri(Register Rd, Register Rn, int imm, int W = 0)
|
||||
{
|
||||
return XFERI(AL, 1, calcU(imm), 0, W, 0, Rn, Rd, abs(imm));
|
||||
}
|
||||
inline int strb(int Rd, int Rn, int Rm)
|
||||
inline int strb(Register Rd, Register Rn, Register Rm)
|
||||
{
|
||||
return XFER(AL, 1, 1, 1, 0, 0, Rn, Rd, 0, 0, Rm);
|
||||
}
|
||||
inline int strbi(int Rd, int Rn, int imm)
|
||||
inline int strbi(Register Rd, Register Rn, int imm)
|
||||
{
|
||||
return XFERI(AL, 1, calcU(imm), 1, 0, 0, Rn, Rd, abs(imm));
|
||||
}
|
||||
inline int ldrh(int Rd, int Rn, int Rm)
|
||||
inline int ldrh(Register Rd, Register Rn, Register Rm)
|
||||
{
|
||||
return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 0, 1, Rm);
|
||||
}
|
||||
inline int ldrhi(int Rd, int Rn, int imm)
|
||||
inline int ldrhi(Register Rd, Register Rn, int imm)
|
||||
{
|
||||
return XFER2I(AL,
|
||||
1,
|
||||
@ -341,11 +341,11 @@ inline int ldrhi(int Rd, int Rn, int imm)
|
||||
1,
|
||||
abs(imm) & 0xf);
|
||||
}
|
||||
inline int strh(int Rd, int Rn, int Rm)
|
||||
inline int strh(Register Rd, Register Rn, Register Rm)
|
||||
{
|
||||
return XFER2(AL, 1, 1, 0, 0, Rn, Rd, 0, 1, Rm);
|
||||
}
|
||||
inline int strhi(int Rd, int Rn, int imm)
|
||||
inline int strhi(Register Rd, Register Rn, int imm)
|
||||
{
|
||||
return XFER2I(AL,
|
||||
1,
|
||||
@ -359,11 +359,11 @@ inline int strhi(int Rd, int Rn, int imm)
|
||||
1,
|
||||
abs(imm) & 0xf);
|
||||
}
|
||||
inline int ldrsh(int Rd, int Rn, int Rm)
|
||||
inline int ldrsh(Register Rd, Register Rn, Register Rm)
|
||||
{
|
||||
return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 1, 1, Rm);
|
||||
}
|
||||
inline int ldrshi(int Rd, int Rn, int imm)
|
||||
inline int ldrshi(Register Rd, Register Rn, int imm)
|
||||
{
|
||||
return XFER2I(AL,
|
||||
1,
|
||||
@ -377,11 +377,11 @@ inline int ldrshi(int Rd, int Rn, int imm)
|
||||
1,
|
||||
abs(imm) & 0xf);
|
||||
}
|
||||
inline int ldrsb(int Rd, int Rn, int Rm)
|
||||
inline int ldrsb(Register Rd, Register Rn, Register Rm)
|
||||
{
|
||||
return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 1, 0, Rm);
|
||||
}
|
||||
inline int ldrsbi(int Rd, int Rn, int imm)
|
||||
inline int ldrsbi(Register Rd, Register Rn, int imm)
|
||||
{
|
||||
return XFER2I(AL,
|
||||
1,
|
||||
@ -403,70 +403,70 @@ inline int bkpt(int16_t immed)
|
||||
// COPROCESSOR INSTRUCTIONS
|
||||
inline int mcr(int coproc,
|
||||
int opcode_1,
|
||||
int Rd,
|
||||
int CRn,
|
||||
int CRm,
|
||||
Register Rd,
|
||||
Register CRn,
|
||||
Register CRm,
|
||||
int opcode_2 = 0)
|
||||
{
|
||||
return COREG(AL, opcode_1, 0, CRn, Rd, coproc, opcode_2, CRm);
|
||||
}
|
||||
inline int mcrr(int coproc, int opcode, int Rd, int Rn, int CRm)
|
||||
inline int mcrr(int coproc, int opcode, Register Rd, Register Rn, Register CRm)
|
||||
{
|
||||
return COREG2(AL, 0, Rn, Rd, coproc, opcode, CRm);
|
||||
}
|
||||
inline int mrc(int coproc,
|
||||
int opcode_1,
|
||||
int Rd,
|
||||
int CRn,
|
||||
int CRm,
|
||||
Register Rd,
|
||||
Register CRn,
|
||||
Register CRm,
|
||||
int opcode_2 = 0)
|
||||
{
|
||||
return COREG(AL, opcode_1, 1, CRn, Rd, coproc, opcode_2, CRm);
|
||||
}
|
||||
inline int mrrc(int coproc, int opcode, int Rd, int Rn, int CRm)
|
||||
inline int mrrc(int coproc, int opcode, Register Rd, Register Rn, Register CRm)
|
||||
{
|
||||
return COREG2(AL, 1, Rn, Rd, coproc, opcode, CRm);
|
||||
}
|
||||
// VFP FLOATING-POINT INSTRUCTIONS
|
||||
inline int fmuls(int Sd, int Sn, int Sm)
|
||||
inline int fmuls(Register Sd, Register Sn, Register Sm)
|
||||
{
|
||||
return COOP(AL,
|
||||
(Sd & 1) << 2 | 2,
|
||||
Sn >> 1,
|
||||
Sd >> 1,
|
||||
((int8_t)Sd & 1) << 2 | 2,
|
||||
(int8_t)Sn >> 1,
|
||||
(int8_t)Sd >> 1,
|
||||
10,
|
||||
(Sn & 1) << 2 | (Sm & 1),
|
||||
Sm >> 1);
|
||||
((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1),
|
||||
(int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fadds(int Sd, int Sn, int Sm)
|
||||
inline int fadds(Register Sd, Register Sn, Register Sm)
|
||||
{
|
||||
return COOP(AL,
|
||||
(Sd & 1) << 2 | 3,
|
||||
Sn >> 1,
|
||||
Sd >> 1,
|
||||
((int8_t)Sd & 1) << 2 | 3,
|
||||
(int8_t)Sn >> 1,
|
||||
(int8_t)Sd >> 1,
|
||||
10,
|
||||
(Sn & 1) << 2 | (Sm & 1),
|
||||
Sm >> 1);
|
||||
((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1),
|
||||
(int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fsubs(int Sd, int Sn, int Sm)
|
||||
inline int fsubs(Register Sd, Register Sn, Register Sm)
|
||||
{
|
||||
return COOP(AL,
|
||||
(Sd & 1) << 2 | 3,
|
||||
Sn >> 1,
|
||||
Sd >> 1,
|
||||
((int8_t)Sd & 1) << 2 | 3,
|
||||
(int8_t)Sn >> 1,
|
||||
(int8_t)Sd >> 1,
|
||||
10,
|
||||
(Sn & 1) << 2 | (Sm & 1) | 2,
|
||||
Sm >> 1);
|
||||
((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1) | 2,
|
||||
(int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fdivs(int Sd, int Sn, int Sm)
|
||||
inline int fdivs(Register Sd, Register Sn, Register Sm)
|
||||
{
|
||||
return COOP(AL,
|
||||
(Sd & 1) << 2 | 8,
|
||||
Sn >> 1,
|
||||
Sd >> 1,
|
||||
((int8_t)Sd & 1) << 2 | 8,
|
||||
(int8_t)Sn >> 1,
|
||||
(int8_t)Sd >> 1,
|
||||
10,
|
||||
(Sn & 1) << 2 | (Sm & 1),
|
||||
Sm >> 1);
|
||||
((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1),
|
||||
(int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fmuld(int Dd, int Dn, int Dm)
|
||||
{
|
||||
@ -484,37 +484,37 @@ inline int fdivd(int Dd, int Dn, int Dm)
|
||||
{
|
||||
return COOP(AL, 8, Dn, Dd, 11, 0, Dm);
|
||||
}
|
||||
inline int fcpys(int Sd, int Sm)
|
||||
inline int fcpys(Register Sd, Register Sm)
|
||||
{
|
||||
return COOP(AL, 0xb | (Sd & 1) << 2, 0, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1);
|
||||
return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0, (int8_t)Sd >> 1, 10, 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fabss(int Sd, int Sm)
|
||||
inline int fabss(Register Sd, Register Sm)
|
||||
{
|
||||
return COOP(AL, 0xb | (Sd & 1) << 2, 0, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1);
|
||||
return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fnegs(int Sd, int Sm)
|
||||
inline int fnegs(Register Sd, Register Sm)
|
||||
{
|
||||
return COOP(AL, 0xb | (Sd & 1) << 2, 1, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1);
|
||||
return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 1, (int8_t)Sd >> 1, 10, 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fsqrts(int Sd, int Sm)
|
||||
inline int fsqrts(Register Sd, Register Sm)
|
||||
{
|
||||
return COOP(AL, 0xb | (Sd & 1) << 2, 1, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1);
|
||||
return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 1, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fcmps(int Sd, int Sm)
|
||||
inline int fcmps(Register Sd, Register Sm)
|
||||
{
|
||||
return COOP(AL, 0xb | (Sd & 1) << 2, 4, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1);
|
||||
return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 4, (int8_t)Sd >> 1, 10, 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fcvtds(int Dd, int Sm)
|
||||
inline int fcvtds(int Dd, Register Sm)
|
||||
{
|
||||
return COOP(AL, 0xb, 7, Dd, 10, 6 | (Sm & 1), Sm >> 1);
|
||||
return COOP(AL, 0xb, 7, Dd, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fsitos(int Sd, int Sm)
|
||||
inline int fsitos(Register Sd, Register Sm)
|
||||
{
|
||||
return COOP(AL, 0xb | (Sd & 1) << 2, 8, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1);
|
||||
return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 8, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1);
|
||||
}
|
||||
inline int ftosizs(int Sd, int Sm)
|
||||
inline int ftosizs(Register Sd, Register Sm)
|
||||
{
|
||||
return COOP(AL, 0xb | (Sd & 1) << 2, 0xd, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1);
|
||||
return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0xd, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1);
|
||||
}
|
||||
inline int fcpyd(int Dd, int Dm)
|
||||
{
|
||||
@ -538,55 +538,55 @@ inline int fcmpd(int Dd, int Dm)
|
||||
return COOP(AL, 0xb, 4, Dd, 11, 2, Dm);
|
||||
}
|
||||
// double-precision conversion instructions
|
||||
inline int fcvtsd(int Sd, int Dm)
|
||||
inline int fcvtsd(Register Sd, int Dm)
|
||||
{
|
||||
return COOP(AL, 0xb | (Sd & 1) << 2, 7, Sd >> 1, 11, 6, Dm);
|
||||
return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 7, (int8_t)Sd >> 1, 11, 6, Dm);
|
||||
}
|
||||
inline int fsitod(int Dd, int Sm)
|
||||
inline int fsitod(Register Dd, Register Sm)
|
||||
{
|
||||
return COOP(AL, 0xb, 8, Dd, 11, 6 | (Sm & 1), Sm >> 1);
|
||||
return COOP(AL, 0xb, 8, Dd, 11, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1);
|
||||
}
|
||||
inline int ftosizd(int Sd, int Dm)
|
||||
inline int ftosizd(Register Sd, Register Dm)
|
||||
{
|
||||
return COOP(AL, 0xb | (Sd & 1) << 2, 0xd, Sd >> 1, 11, 6, Dm);
|
||||
return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0xd, (int8_t)Sd >> 1, 11, 6, Dm);
|
||||
}
|
||||
// single load/store instructions for both precision types
|
||||
inline int flds(int Sd, int Rn, int offset = 0)
|
||||
inline int flds(Register Sd, Register Rn, int offset = 0)
|
||||
{
|
||||
return COXFER(AL, 1, 1, Sd & 1, 0, 1, Rn, Sd >> 1, 10, offset);
|
||||
return COXFER(AL, 1, 1, (int8_t)Sd & 1, 0, 1, Rn, (int8_t)Sd >> 1, 10, offset);
|
||||
};
|
||||
inline int fldd(int Dd, int Rn, int offset = 0)
|
||||
inline int fldd(Register Dd, Register Rn, int offset = 0)
|
||||
{
|
||||
return COXFER(AL, 1, 1, 0, 0, 1, Rn, Dd, 11, offset);
|
||||
};
|
||||
inline int fsts(int Sd, int Rn, int offset = 0)
|
||||
inline int fsts(Register Sd, Register Rn, int offset = 0)
|
||||
{
|
||||
return COXFER(AL, 1, 1, Sd & 1, 0, 0, Rn, Sd >> 1, 10, offset);
|
||||
return COXFER(AL, 1, 1, (int8_t)Sd & 1, 0, 0, Rn, (int8_t)Sd >> 1, 10, offset);
|
||||
};
|
||||
inline int fstd(int Dd, int Rn, int offset = 0)
|
||||
inline int fstd(Register Dd, Register Rn, int offset = 0)
|
||||
{
|
||||
return COXFER(AL, 1, 1, 0, 0, 0, Rn, Dd, 11, offset);
|
||||
};
|
||||
// move between GPRs and FPRs
|
||||
inline int fmsr(int Sn, int Rd)
|
||||
inline int fmsr(Register Sn, Register Rd)
|
||||
{
|
||||
return mcr(10, 0, Rd, Sn >> 1, 0, (Sn & 1) << 2);
|
||||
return mcr(10, 0, Rd, (int8_t)Sn >> 1, 0, ((int8_t)Sn & 1) << 2);
|
||||
}
|
||||
inline int fmrs(int Rd, int Sn)
|
||||
inline int fmrs(Register Rd, Register Sn)
|
||||
{
|
||||
return mrc(10, 0, Rd, Sn >> 1, 0, (Sn & 1) << 2);
|
||||
return mrc(10, 0, Rd, (int8_t)Sn >> 1, 0, ((int8_t)Sn & 1) << 2);
|
||||
}
|
||||
// move to/from VFP system registers
|
||||
inline int fmrx(int Rd, int reg)
|
||||
inline int fmrx(Register Rd, int reg)
|
||||
{
|
||||
return mrc(10, 7, Rd, reg, 0);
|
||||
}
|
||||
// these move around pairs of single-precision registers
|
||||
inline int fmdrr(int Dm, int Rd, int Rn)
|
||||
inline int fmdrr(Register Dm, Register Rd, Register Rn)
|
||||
{
|
||||
return mcrr(11, 1, Rd, Rn, Dm);
|
||||
}
|
||||
inline int fmrrd(int Rd, int Rn, int Dm)
|
||||
inline int fmrrd(Register Rd, Register Rn, int Dm)
|
||||
{
|
||||
return mrrc(11, 1, Rd, Rn, Dm);
|
||||
}
|
||||
@ -600,27 +600,27 @@ inline int SETS(int ins)
|
||||
return ins | 1 << 20;
|
||||
}
|
||||
// PSEUDO-INSTRUCTIONS
|
||||
inline int lsl(int Rd, int Rm, int Rs)
|
||||
inline int lsl(Register Rd, Register Rm, Register Rs)
|
||||
{
|
||||
return movsh(Rd, Rm, Rs, LSL);
|
||||
}
|
||||
inline int lsli(int Rd, int Rm, int imm)
|
||||
inline int lsli(Register Rd, Register Rm, int imm)
|
||||
{
|
||||
return mov(Rd, Rm, LSL, imm);
|
||||
}
|
||||
inline int lsr(int Rd, int Rm, int Rs)
|
||||
inline int lsr(Register Rd, Register Rm, Register Rs)
|
||||
{
|
||||
return movsh(Rd, Rm, Rs, LSR);
|
||||
}
|
||||
inline int lsri(int Rd, int Rm, int imm)
|
||||
inline int lsri(Register Rd, Register Rm, int imm)
|
||||
{
|
||||
return mov(Rd, Rm, LSR, imm);
|
||||
}
|
||||
inline int asr(int Rd, int Rm, int Rs)
|
||||
inline int asr(Register Rd, Register Rm, Register Rs)
|
||||
{
|
||||
return movsh(Rd, Rm, Rs, ASR);
|
||||
}
|
||||
inline int asri(int Rd, int Rm, int imm)
|
||||
inline int asri(Register Rd, Register Rm, int imm)
|
||||
{
|
||||
return mov(Rd, Rm, ASR, imm);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ void shiftLeftR(Context* con,
|
||||
lir::RegisterPair* t)
|
||||
{
|
||||
if (size == 8) {
|
||||
int tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con);
|
||||
Register tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con);
|
||||
ResolvedPromise maskPromise(0x3F);
|
||||
lir::Constant mask(&maskPromise);
|
||||
lir::RegisterPair dst(tmp3);
|
||||
@ -61,7 +61,7 @@ void shiftLeftR(Context* con,
|
||||
freeTemp(con, tmp2);
|
||||
freeTemp(con, tmp3);
|
||||
} else {
|
||||
int tmp = newTemp(con);
|
||||
Register tmp = newTemp(con);
|
||||
ResolvedPromise maskPromise(0x1F);
|
||||
lir::Constant mask(&maskPromise);
|
||||
lir::RegisterPair dst(tmp);
|
||||
@ -98,7 +98,7 @@ void shiftRightR(Context* con,
|
||||
lir::RegisterPair* t)
|
||||
{
|
||||
if (size == 8) {
|
||||
int tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con);
|
||||
Register tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con);
|
||||
ResolvedPromise maskPromise(0x3F);
|
||||
lir::Constant mask(&maskPromise);
|
||||
lir::RegisterPair dst(tmp3);
|
||||
@ -114,7 +114,7 @@ void shiftRightR(Context* con,
|
||||
freeTemp(con, tmp2);
|
||||
freeTemp(con, tmp3);
|
||||
} else {
|
||||
int tmp = newTemp(con);
|
||||
Register tmp = newTemp(con);
|
||||
ResolvedPromise maskPromise(0x1F);
|
||||
lir::Constant mask(&maskPromise);
|
||||
lir::RegisterPair dst(tmp);
|
||||
@ -144,14 +144,14 @@ void unsignedShiftRightR(Context* con,
|
||||
lir::RegisterPair* b,
|
||||
lir::RegisterPair* t)
|
||||
{
|
||||
int tmpShift = newTemp(con);
|
||||
Register tmpShift = newTemp(con);
|
||||
ResolvedPromise maskPromise(size == 8 ? 0x3F : 0x1F);
|
||||
lir::Constant mask(&maskPromise);
|
||||
lir::RegisterPair dst(tmpShift);
|
||||
andC(con, 4, &mask, a, &dst);
|
||||
emit(con, lsr(t->low, b->low, tmpShift));
|
||||
if (size == 8) {
|
||||
int tmpHi = newTemp(con), tmpLo = newTemp(con);
|
||||
Register tmpHi = newTemp(con), tmpLo = newTemp(con);
|
||||
emit(con, SETS(rsbi(tmpHi, tmpShift, 32)));
|
||||
emit(con, lsl(tmpLo, b->high, tmpHi));
|
||||
emit(con, orr(t->low, t->low, tmpLo));
|
||||
@ -509,9 +509,9 @@ void multiplyR(Context* con,
|
||||
{
|
||||
if (size == 8) {
|
||||
bool useTemporaries = b->low == t->low;
|
||||
int tmpLow = useTemporaries ? con->client->acquireTemporary(GPR_MASK)
|
||||
Register tmpLow = useTemporaries ? con->client->acquireTemporary(GPR_MASK)
|
||||
: t->low;
|
||||
int tmpHigh = useTemporaries ? con->client->acquireTemporary(GPR_MASK)
|
||||
Register tmpHigh = useTemporaries ? con->client->acquireTemporary(GPR_MASK)
|
||||
: t->high;
|
||||
|
||||
emit(con, umull(tmpLow, tmpHigh, a->low, b->low));
|
||||
@ -574,8 +574,8 @@ void float2IntRR(Context* con,
|
||||
unsigned,
|
||||
lir::RegisterPair* b)
|
||||
{
|
||||
int tmp = newTemp(con, FPR_MASK);
|
||||
int ftmp = fpr32(tmp);
|
||||
Register tmp = newTemp(con, FPR_MASK);
|
||||
Register ftmp = fpr32(tmp);
|
||||
if (size == 8) { // double to int
|
||||
emit(con, ftosizd(ftmp, fpr64(a)));
|
||||
} else { // float to int
|
||||
@ -664,9 +664,9 @@ void floatDivideR(Context* con,
|
||||
}
|
||||
}
|
||||
|
||||
int normalize(Context* con,
|
||||
Register normalize(Context* con,
|
||||
int offset,
|
||||
int index,
|
||||
Register index,
|
||||
unsigned scale,
|
||||
bool* preserveIndex,
|
||||
bool* release)
|
||||
@ -682,7 +682,7 @@ int normalize(Context* con,
|
||||
*release = false;
|
||||
}
|
||||
|
||||
int scaled;
|
||||
Register scaled;
|
||||
|
||||
if (scale != 1) {
|
||||
lir::RegisterPair unscaledIndex(index);
|
||||
@ -731,15 +731,15 @@ int normalize(Context* con,
|
||||
void store(Context* con,
|
||||
unsigned size,
|
||||
lir::RegisterPair* src,
|
||||
int base,
|
||||
Register base,
|
||||
int offset,
|
||||
int index,
|
||||
Register index,
|
||||
unsigned scale,
|
||||
bool preserveIndex)
|
||||
{
|
||||
if (index != lir::NoRegister) {
|
||||
if (index != Register::None) {
|
||||
bool release;
|
||||
int normalized
|
||||
Register normalized
|
||||
= normalize(con, offset, index, scale, &preserveIndex, &release);
|
||||
|
||||
if (!isFpr(src)) { // GPR store
|
||||
@ -799,8 +799,8 @@ void store(Context* con,
|
||||
|
||||
case 8: { // split into 2 32-bit stores
|
||||
lir::RegisterPair srcHigh(src->high);
|
||||
store(con, 4, &srcHigh, base, offset, lir::NoRegister, 1, false);
|
||||
store(con, 4, src, base, offset + 4, lir::NoRegister, 1, false);
|
||||
store(con, 4, &srcHigh, base, offset, Register::None, 1, false);
|
||||
store(con, 4, src, base, offset + 4, Register::None, 1, false);
|
||||
} break;
|
||||
|
||||
default:
|
||||
@ -844,18 +844,18 @@ void moveRM(Context* con,
|
||||
|
||||
void load(Context* con,
|
||||
unsigned srcSize,
|
||||
int base,
|
||||
Register base,
|
||||
int offset,
|
||||
int index,
|
||||
Register index,
|
||||
unsigned scale,
|
||||
unsigned dstSize,
|
||||
lir::RegisterPair* dst,
|
||||
bool preserveIndex,
|
||||
bool signExtend)
|
||||
{
|
||||
if (index != lir::NoRegister) {
|
||||
if (index != Register::None) {
|
||||
bool release;
|
||||
int normalized
|
||||
Register normalized
|
||||
= normalize(con, offset, index, scale, &preserveIndex, &release);
|
||||
|
||||
if (!isFpr(dst)) { // GPR load
|
||||
@ -951,7 +951,7 @@ void load(Context* con,
|
||||
4,
|
||||
base,
|
||||
offset,
|
||||
lir::NoRegister,
|
||||
Register::None,
|
||||
1,
|
||||
4,
|
||||
&dstHigh,
|
||||
@ -961,7 +961,7 @@ void load(Context* con,
|
||||
4,
|
||||
base,
|
||||
offset + 4,
|
||||
lir::NoRegister,
|
||||
Register::None,
|
||||
1,
|
||||
4,
|
||||
dst,
|
||||
|
@ -59,9 +59,9 @@ inline lir::RegisterPair makeTemp64(Context* con)
|
||||
|
||||
inline void freeTemp(Context* con, const lir::RegisterPair& tmp)
|
||||
{
|
||||
if (tmp.low != lir::NoRegister)
|
||||
if (tmp.low != Register::None)
|
||||
freeTemp(con, tmp.low);
|
||||
if (tmp.high != lir::NoRegister)
|
||||
if (tmp.high != Register::None)
|
||||
freeTemp(con, tmp.high);
|
||||
}
|
||||
|
||||
|
@ -28,18 +28,18 @@ const RegisterMask FPR_MASK = 0xffff0000;
|
||||
|
||||
inline bool isFpr(lir::RegisterPair* reg)
|
||||
{
|
||||
return reg->low >= N_GPRS;
|
||||
return (int8_t)reg->low >= N_GPRS;
|
||||
}
|
||||
|
||||
inline int fpr64(int reg)
|
||||
inline int fpr64(Register reg)
|
||||
{
|
||||
return reg - N_GPRS;
|
||||
return (int8_t)reg - N_GPRS;
|
||||
}
|
||||
inline int fpr64(lir::RegisterPair* reg)
|
||||
{
|
||||
return fpr64(reg->low);
|
||||
}
|
||||
inline int fpr32(int reg)
|
||||
inline int fpr32(Register reg)
|
||||
{
|
||||
return fpr64(reg) << 1;
|
||||
}
|
||||
|
@ -183,37 +183,37 @@ class MyArchitecture : public Architecture {
|
||||
return &myRegisterFile;
|
||||
}
|
||||
|
||||
virtual int scratch()
|
||||
virtual Register scratch()
|
||||
{
|
||||
return rax;
|
||||
}
|
||||
|
||||
virtual int stack()
|
||||
virtual Register stack()
|
||||
{
|
||||
return rsp;
|
||||
}
|
||||
|
||||
virtual int thread()
|
||||
virtual Register thread()
|
||||
{
|
||||
return rbx;
|
||||
}
|
||||
|
||||
virtual int returnLow()
|
||||
virtual Register returnLow()
|
||||
{
|
||||
return rax;
|
||||
}
|
||||
|
||||
virtual int returnHigh()
|
||||
virtual Register returnHigh()
|
||||
{
|
||||
return (TargetBytesPerWord == 4 ? rdx : lir::NoRegister);
|
||||
return (TargetBytesPerWord == 4 ? rdx : Register::None);
|
||||
}
|
||||
|
||||
virtual int virtualCallTarget()
|
||||
virtual Register virtualCallTarget()
|
||||
{
|
||||
return rax;
|
||||
}
|
||||
|
||||
virtual int virtualCallIndex()
|
||||
virtual Register virtualCallIndex()
|
||||
{
|
||||
return rdx;
|
||||
}
|
||||
@ -233,9 +233,9 @@ class MyArchitecture : public Architecture {
|
||||
return 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
virtual bool reserved(int register_)
|
||||
virtual bool reserved(Register register_)
|
||||
{
|
||||
switch (register_) {
|
||||
switch ((int8_t)register_) {
|
||||
case rbp:
|
||||
return UseFramePointer;
|
||||
|
||||
@ -289,7 +289,7 @@ class MyArchitecture : public Architecture {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int argumentRegister(unsigned index)
|
||||
virtual Register argumentRegister(unsigned index)
|
||||
{
|
||||
assertT(&c, TargetBytesPerWord == 8);
|
||||
switch (index) {
|
||||
@ -1031,8 +1031,8 @@ class MyAssembler : public Assembler {
|
||||
|
||||
virtual void popFrameForTailCall(unsigned frameFootprint,
|
||||
int offset,
|
||||
int returnAddressSurrogate,
|
||||
int framePointerSurrogate)
|
||||
Register returnAddressSurrogate,
|
||||
Register framePointerSurrogate)
|
||||
{
|
||||
if (TailCalls) {
|
||||
if (offset) {
|
||||
@ -1070,7 +1070,7 @@ class MyAssembler : public Assembler {
|
||||
|
||||
addCR(&c, TargetBytesPerWord, &footprint, TargetBytesPerWord, &stack);
|
||||
|
||||
if (returnAddressSurrogate != lir::NoRegister) {
|
||||
if (returnAddressSurrogate != Register::None) {
|
||||
assertT(&c, offset > 0);
|
||||
|
||||
lir::RegisterPair ras(returnAddressSurrogate);
|
||||
@ -1078,7 +1078,7 @@ class MyAssembler : public Assembler {
|
||||
moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst);
|
||||
}
|
||||
|
||||
if (framePointerSurrogate != lir::NoRegister) {
|
||||
if (framePointerSurrogate != Register::None) {
|
||||
assertT(&c, offset > 0);
|
||||
|
||||
lir::RegisterPair fps(framePointerSurrogate);
|
||||
|
@ -53,9 +53,9 @@ namespace x86 {
|
||||
|
||||
void maybeRex(Context* c,
|
||||
unsigned size,
|
||||
int a,
|
||||
int index,
|
||||
int base,
|
||||
Register a,
|
||||
Register index,
|
||||
Register base,
|
||||
bool always)
|
||||
{
|
||||
if (vm::TargetBytesPerWord == 8) {
|
||||
@ -65,11 +65,11 @@ void maybeRex(Context* c,
|
||||
} else {
|
||||
byte = REX_NONE;
|
||||
}
|
||||
if (a != lir::NoRegister and (a & 8))
|
||||
if (a != Register::None and ((int8_t)a & 8))
|
||||
byte |= REX_R;
|
||||
if (index != lir::NoRegister and (index & 8))
|
||||
if (index != Register::None and ((int8_t)index & 8))
|
||||
byte |= REX_X;
|
||||
if (base != lir::NoRegister and (base & 8))
|
||||
if (base != Register::None and ((int8_t)base & 8))
|
||||
byte |= REX_B;
|
||||
if (always or byte != REX_NONE)
|
||||
c->code.append(byte);
|
||||
@ -78,30 +78,30 @@ void maybeRex(Context* c,
|
||||
|
||||
void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b)
|
||||
{
|
||||
maybeRex(c, size, a->low, lir::NoRegister, b->low, false);
|
||||
maybeRex(c, size, a->low, Register::None, b->low, false);
|
||||
}
|
||||
|
||||
void alwaysRex(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b)
|
||||
{
|
||||
maybeRex(c, size, a->low, lir::NoRegister, b->low, true);
|
||||
maybeRex(c, size, a->low, Register::None, b->low, true);
|
||||
}
|
||||
|
||||
void maybeRex(Context* c, unsigned size, lir::RegisterPair* a)
|
||||
{
|
||||
maybeRex(c, size, lir::NoRegister, lir::NoRegister, a->low, false);
|
||||
maybeRex(c, size, Register::None, Register::None, a->low, false);
|
||||
}
|
||||
|
||||
void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::Memory* b)
|
||||
{
|
||||
maybeRex(c, size, a->low, b->index, b->base, size == 1 and (a->low & 4));
|
||||
maybeRex(c, size, a->low, b->index, b->base, size == 1 and ((int8_t)a->low & 4));
|
||||
}
|
||||
|
||||
void maybeRex(Context* c, unsigned size, lir::Memory* a)
|
||||
{
|
||||
maybeRex(c, size, lir::NoRegister, a->index, a->base, false);
|
||||
maybeRex(c, size, Register::None, a->index, a->base, false);
|
||||
}
|
||||
|
||||
void modrm(Context* c, uint8_t mod, int a, int b)
|
||||
void modrm(Context* c, uint8_t mod, Register a, Register b)
|
||||
{
|
||||
c->code.append(mod | (regCode(b) << 3) | regCode(a));
|
||||
}
|
||||
@ -111,15 +111,15 @@ void modrm(Context* c, uint8_t mod, lir::RegisterPair* a, lir::RegisterPair* b)
|
||||
modrm(c, mod, a->low, b->low);
|
||||
}
|
||||
|
||||
void sib(Context* c, unsigned scale, int index, int base)
|
||||
void sib(Context* c, unsigned scale, Register index, Register base)
|
||||
{
|
||||
c->code.append((util::log(scale) << 6) | (regCode(index) << 3)
|
||||
| regCode(base));
|
||||
}
|
||||
|
||||
void modrmSib(Context* c, int width, int a, int scale, int index, int base)
|
||||
void modrmSib(Context* c, int width, Register a, int scale, Register index, Register base)
|
||||
{
|
||||
if (index == lir::NoRegister) {
|
||||
if (index == Register::None) {
|
||||
modrm(c, width, base, a);
|
||||
if (regCode(base) == rsp) {
|
||||
sib(c, 0x00, rsp, rsp);
|
||||
@ -130,7 +130,7 @@ void modrmSib(Context* c, int width, int a, int scale, int index, int base)
|
||||
}
|
||||
}
|
||||
|
||||
void modrmSibImm(Context* c, int a, int scale, int index, int base, int offset)
|
||||
void modrmSibImm(Context* c, Register a, int scale, Register index, Register base, int offset)
|
||||
{
|
||||
if (offset == 0 and regCode(base) != rbp) {
|
||||
modrmSib(c, 0x00, a, scale, index, base);
|
||||
|
@ -42,9 +42,9 @@ void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::Memory* b);
|
||||
|
||||
void maybeRex(Context* c, unsigned size, lir::Memory* a);
|
||||
|
||||
inline int regCode(int a)
|
||||
inline int regCode(Register a)
|
||||
{
|
||||
return a & 7;
|
||||
return (int8_t)a & 7;
|
||||
}
|
||||
|
||||
inline int regCode(lir::RegisterPair* a)
|
||||
@ -54,18 +54,18 @@ inline int regCode(lir::RegisterPair* a)
|
||||
|
||||
inline bool isFloatReg(lir::RegisterPair* a)
|
||||
{
|
||||
return a->low >= xmm0;
|
||||
return (int8_t)a->low >= xmm0;
|
||||
}
|
||||
|
||||
void modrm(Context* c, uint8_t mod, int a, int b);
|
||||
void modrm(Context* c, uint8_t mod, Register a, Register b);
|
||||
|
||||
void modrm(Context* c, uint8_t mod, lir::RegisterPair* a, lir::RegisterPair* b);
|
||||
|
||||
void sib(Context* c, unsigned scale, int index, int base);
|
||||
void sib(Context* c, unsigned scale, Register index, Register base);
|
||||
|
||||
void modrmSib(Context* c, int width, int a, int scale, int index, int base);
|
||||
void modrmSib(Context* c, int width, Register a, int scale, Register index, Register base);
|
||||
|
||||
void modrmSibImm(Context* c, int a, int scale, int index, int base, int offset);
|
||||
void modrmSibImm(Context* c, Register a, int scale, Register index, Register base, int offset);
|
||||
|
||||
void modrmSibImm(Context* c, lir::RegisterPair* a, lir::Memory* b);
|
||||
|
||||
|
@ -308,8 +308,8 @@ void moveRR(Context* c,
|
||||
} else {
|
||||
switch (aSize) {
|
||||
case 1:
|
||||
if (vm::TargetBytesPerWord == 4 and a->low > rbx) {
|
||||
assertT(c, b->low <= rbx);
|
||||
if (vm::TargetBytesPerWord == 4 and (int8_t)a->low > rbx) {
|
||||
assertT(c, (int8_t)b->low <= rbx);
|
||||
|
||||
moveRR(c, vm::TargetBytesPerWord, a, vm::TargetBytesPerWord, b);
|
||||
moveRR(c, 1, b, vm::TargetBytesPerWord, b);
|
||||
@ -986,7 +986,7 @@ void multiplyRR(Context* c,
|
||||
addRR(c, 4, &bh, 4, scratch);
|
||||
|
||||
// mul a->low,%eax%edx
|
||||
opcode(c, 0xf7, 0xe0 + a->low);
|
||||
opcode(c, 0xf7, 0xe0 + (int8_t)a->low);
|
||||
|
||||
addRR(c, 4, scratch, 4, &bh);
|
||||
moveRR(c, 4, &axdx, 4, b);
|
||||
@ -1403,7 +1403,7 @@ void shiftLeftRR(Context* c,
|
||||
modrm(c, 0xc0, b->high, b->low);
|
||||
|
||||
// shl
|
||||
opcode(c, 0xd3, 0xe0 + b->low);
|
||||
opcode(c, 0xd3, 0xe0 + (int8_t)b->low);
|
||||
|
||||
ResolvedPromise promise(32);
|
||||
lir::Constant constant(&promise);
|
||||
@ -1454,7 +1454,7 @@ void shiftRightRR(Context* c,
|
||||
modrm(c, 0xc0, b->low, b->high);
|
||||
|
||||
// sar
|
||||
opcode(c, 0xd3, 0xf8 + b->high);
|
||||
opcode(c, 0xd3, 0xf8 + (int8_t)b->high);
|
||||
|
||||
ResolvedPromise promise(32);
|
||||
lir::Constant constant(&promise);
|
||||
@ -1468,7 +1468,7 @@ void shiftRightRR(Context* c,
|
||||
moveRR(c, 4, &bh, 4, b); // 2 bytes
|
||||
|
||||
// sar 31,high
|
||||
opcode(c, 0xc1, 0xf8 + b->high);
|
||||
opcode(c, 0xc1, 0xf8 + (int8_t)b->high);
|
||||
c->code.append(31);
|
||||
} else {
|
||||
assertT(c, a->low == rcx);
|
||||
@ -1508,7 +1508,7 @@ void unsignedShiftRightRR(Context* c,
|
||||
modrm(c, 0xc0, b->low, b->high);
|
||||
|
||||
// shr
|
||||
opcode(c, 0xd3, 0xe8 + b->high);
|
||||
opcode(c, 0xd3, 0xe8 + (int8_t)b->high);
|
||||
|
||||
ResolvedPromise promise(32);
|
||||
lir::Constant constant(&promise);
|
||||
|
@ -25,12 +25,12 @@ TEST(RegisterIterator)
|
||||
|
||||
RegisterIterator it(regs);
|
||||
assertTrue(it.hasNext());
|
||||
assertEqual<unsigned>(0, it.next());
|
||||
assertEqual<unsigned>(0, (int8_t)it.next());
|
||||
assertTrue(it.hasNext());
|
||||
assertEqual<unsigned>(2, it.next());
|
||||
assertEqual<unsigned>(2, (int8_t)it.next());
|
||||
assertTrue(it.hasNext());
|
||||
assertEqual<unsigned>(4, it.next());
|
||||
assertEqual<unsigned>(4, (int8_t)it.next());
|
||||
assertTrue(it.hasNext());
|
||||
assertEqual<unsigned>(6, it.next());
|
||||
assertEqual<unsigned>(6, (int8_t)it.next());
|
||||
assertFalse(it.hasNext());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user