mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
snapshot
This commit is contained in:
parent
23197da679
commit
609a1a9633
@ -38,22 +38,11 @@ enum UnaryOperation {
|
||||
Jump,
|
||||
LongJump,
|
||||
AlignedJump,
|
||||
JumpIfLess,
|
||||
JumpIfGreater,
|
||||
JumpIfLessOrEqual,
|
||||
JumpIfGreaterOrEqual,
|
||||
JumpIfEqual,
|
||||
JumpIfNotEqual,
|
||||
JumpIfFloatUnordered,
|
||||
JumpIfFloatLess,
|
||||
JumpIfFloatGreater,
|
||||
JumpIfFloatLessOrEqual,
|
||||
JumpIfFloatGreaterOrEqual,
|
||||
JumpIfFloatEqual,
|
||||
JumpIfFloatNotEqual,
|
||||
|
||||
NoUnaryOperation = -1
|
||||
};
|
||||
|
||||
const unsigned UnaryOperationCount = JumpIfNotEqual + 1;
|
||||
const unsigned UnaryOperationCount = AlignedJump + 1;
|
||||
|
||||
enum BinaryOperation {
|
||||
Move,
|
||||
@ -62,15 +51,11 @@ enum BinaryOperation {
|
||||
MoveZ,
|
||||
Compare,
|
||||
Negate,
|
||||
|
||||
//extensions:
|
||||
FloatNegate,
|
||||
FloatCompare,
|
||||
Float2Float,
|
||||
Float2Int,
|
||||
Int2Float,
|
||||
|
||||
//intrinsic functions:
|
||||
FloatSqrt,
|
||||
FloatAbs,
|
||||
Abs,
|
||||
@ -81,7 +66,6 @@ enum BinaryOperation {
|
||||
const unsigned BinaryOperationCount = Abs + 1;
|
||||
|
||||
enum TernaryOperation {
|
||||
LongCompare,
|
||||
Add,
|
||||
Subtract,
|
||||
Multiply,
|
||||
@ -93,22 +77,35 @@ enum TernaryOperation {
|
||||
And,
|
||||
Or,
|
||||
Xor,
|
||||
|
||||
//extensions:
|
||||
FloatAdd,
|
||||
FloatSubtract,
|
||||
FloatMultiply,
|
||||
FloatDivide,
|
||||
FloatRemainder,
|
||||
|
||||
//intrinsic functions:
|
||||
FloatMax,
|
||||
FloatMin,
|
||||
JumpIfLess,
|
||||
JumpIfGreater,
|
||||
JumpIfLessOrEqual,
|
||||
JumpIfGreaterOrEqual,
|
||||
JumpIfEqual,
|
||||
JumpIfNotEqual,
|
||||
JumpIfFloatEqual,
|
||||
JumpIfFloatNotEqual,
|
||||
JumpIfFloatLess,
|
||||
JumpIfFloatGreater,
|
||||
JumpIfFloatLessOrEqual,
|
||||
JumpIfFloatGreaterOrEqual,
|
||||
JumpIfFloatLessOrUnordered,
|
||||
JumpIfFloatGreaterOrUnordered,
|
||||
JumpIfFloatLessOrEqualOrUnordered,
|
||||
JumpIfFloatGreaterOrEqualOrUnordered,
|
||||
|
||||
NoTernaryOperation = -1
|
||||
};
|
||||
|
||||
const unsigned TernaryOperationCount = FloatMin + 1;
|
||||
const unsigned TernaryOperationCount
|
||||
= JumpIfFloatGreaterOrEqualOrUnordered + 1;
|
||||
|
||||
enum OperandType {
|
||||
ConstantOperand,
|
||||
@ -315,8 +312,6 @@ class Assembler {
|
||||
|
||||
virtual unsigned registerSize(ValueType type) = 0;
|
||||
|
||||
virtual bool supportsFloatCompare(unsigned size) = 0;
|
||||
|
||||
virtual bool alwaysCondensed(BinaryOperation op) = 0;
|
||||
virtual bool alwaysCondensed(TernaryOperation op) = 0;
|
||||
|
||||
|
250
src/compile.cpp
250
src/compile.cpp
@ -1971,6 +1971,18 @@ compareFloatsL(uint32_t bi, uint32_t ai)
|
||||
}
|
||||
}
|
||||
|
||||
int64_t
|
||||
compareLongs(uint64_t b, uint64_t a)
|
||||
{
|
||||
if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
addDouble(uint64_t b, uint64_t a)
|
||||
{
|
||||
@ -2677,17 +2689,111 @@ saveStateAndCompile(MyThread* t, Frame* initialFrame, unsigned ip)
|
||||
}
|
||||
|
||||
bool
|
||||
isCJump(unsigned instruction)
|
||||
integerBranch(Frame* frame, object code, unsigned& ip, unsigned size,
|
||||
Compiler::Operand* a, Compiler::Operand* b)
|
||||
{
|
||||
switch(instruction) {
|
||||
if (ip + 3 > codeLength(t, code)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Compiler* c = frame->c;
|
||||
unsigned instruction = codeBody(t, code, ip++);
|
||||
uint32_t offset = codeReadInt16(t, code, ip);
|
||||
uint32_t newIp = (ip - 3) + offset;
|
||||
assert(t, newIp < codeLength(t, code));
|
||||
|
||||
Compiler::Operand* target = frame->machineIp(newIp);
|
||||
|
||||
switch (instruction) {
|
||||
case ifeq:
|
||||
case ifne:
|
||||
case ifgt:
|
||||
case ifge:
|
||||
case iflt:
|
||||
case ifle:
|
||||
c->jumpIfEqual(size, a, b, target);
|
||||
return true;
|
||||
|
||||
case ifne:
|
||||
c->jumpIfNotEqual(size, a, b, target);
|
||||
return true;
|
||||
|
||||
case ifgt:
|
||||
c->jumpIfGreater(size, a, b, target);
|
||||
return true;
|
||||
|
||||
case ifge:
|
||||
c->jumpIfGreaterOrEqual(size, a, b, target);
|
||||
return true;
|
||||
|
||||
case iflt:
|
||||
c->jumpIfLessOrUnordered(size, a, b, target);
|
||||
return true;
|
||||
|
||||
case ifle:
|
||||
c->jumpIfLessOrEqualOrUnordered(size, a, b, target);
|
||||
return true;
|
||||
|
||||
default:
|
||||
ip -= 3;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
floatBranch(Frame* frame, object code, unsigned& ip, unsigned size,
|
||||
bool lessIfUnordered, Compiler::Operand* a, Compiler::Operand* b)
|
||||
{
|
||||
if (ip + 3 > codeLength(t, code)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Compiler* c = frame->c;
|
||||
unsigned instruction = codeBody(t, code, ip++);
|
||||
uint32_t offset = codeReadInt16(t, code, ip);
|
||||
uint32_t newIp = (ip - 3) + offset;
|
||||
assert(t, newIp < codeLength(t, code));
|
||||
|
||||
Compiler::Operand* target = frame->machineIp(newIp);
|
||||
|
||||
switch (instruction) {
|
||||
case ifeq:
|
||||
c->jumpIfFloatEqual(size, a, b, target);
|
||||
return true;
|
||||
|
||||
case ifne:
|
||||
c->jumpIfFloatNotEqual(size, a, b, target);
|
||||
return true;
|
||||
|
||||
case ifgt:
|
||||
if (lessIfUnordered) {
|
||||
c->jumpIfFloatGreater(size, a, b, target);
|
||||
} else {
|
||||
c->jumpIfFloatGreaterOrUnordered(size, a, b, target);
|
||||
}
|
||||
return true;
|
||||
|
||||
case ifge:
|
||||
if (lessIfUnordered) {
|
||||
c->jumpIfFloatGreaterOrEqual(size, a, b, target);
|
||||
} else {
|
||||
c->jumpIfFloatGreaterOrEqualOrUnordered(size, a, b, target);
|
||||
}
|
||||
return true;
|
||||
|
||||
case iflt:
|
||||
if (lessIfUnordered) {
|
||||
c->jumpIfFloatLessOrUnordered(size, a, b, target);
|
||||
} else {
|
||||
c->jumpIfFloatLess(size, a, b, target);
|
||||
}
|
||||
return true;
|
||||
|
||||
case ifle:
|
||||
if (lessIfUnordered) {
|
||||
c->jumpIfFloatLessOrEqualOrUnordered(size, a, b, target);
|
||||
} else {
|
||||
c->jumpIfFloatLessOrEqual(size, a, b, target);
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
ip -= 3;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2706,8 +2812,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
object code = methodCode(t, context->method);
|
||||
PROTECT(t, code);
|
||||
|
||||
int lastFcmpl = 1, lastFcmpg = 1;
|
||||
|
||||
while (ip < codeLength(t, code)) {
|
||||
if (context->visitTable[ip] ++) {
|
||||
// we've already visited this part of the code
|
||||
@ -2733,9 +2837,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
1, c->register_(t->arch->thread()));
|
||||
}
|
||||
|
||||
++ lastFcmpl;
|
||||
++ lastFcmpg;
|
||||
|
||||
// fprintf(stderr, "ip: %d map: %ld\n", ip, *(frame->map));
|
||||
|
||||
unsigned instruction = codeBody(t, code, ip++);
|
||||
@ -3043,10 +3144,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::Operand* a = frame->popLong();
|
||||
Compiler::Operand* b = frame->popLong();
|
||||
|
||||
if(t->arch->supportsFloatCompare(8) and isCJump(codeBody(t, code, ip))) {
|
||||
c->fcmp(8, a, b);
|
||||
lastFcmpg = 0;
|
||||
} else {
|
||||
if (not floatBranch(frame, ip, 8, false, a, b)) {
|
||||
frame->pushInt
|
||||
(c->call
|
||||
(c->constant
|
||||
@ -3061,10 +3159,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::Operand* a = frame->popLong();
|
||||
Compiler::Operand* b = frame->popLong();
|
||||
|
||||
if(t->arch->supportsFloatCompare(8) and isCJump(codeBody(t, code, ip))) {
|
||||
c->fcmp(8, a, b);
|
||||
lastFcmpl = 0;
|
||||
} else {
|
||||
if (not floatBranch(frame, ip, 8, true, a, b)) {
|
||||
frame->pushInt
|
||||
(c->call
|
||||
(c->constant
|
||||
@ -3162,10 +3257,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::Operand* a = frame->popInt();
|
||||
Compiler::Operand* b = frame->popInt();
|
||||
|
||||
if(t->arch->supportsFloatCompare(4) and isCJump(codeBody(t, code, ip))) {
|
||||
c->fcmp(4, a, b);
|
||||
lastFcmpg = 0;
|
||||
} else {
|
||||
if (not floatBranch(frame, ip, 4, false, a, b)) {
|
||||
frame->pushInt
|
||||
(c->call
|
||||
(c->constant
|
||||
@ -3178,10 +3270,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::Operand* a = frame->popInt();
|
||||
Compiler::Operand* b = frame->popInt();
|
||||
|
||||
if(t->arch->supportsFloatCompare(4) and isCJump(codeBody(t, code, ip))) {
|
||||
c->fcmp(4, a, b);
|
||||
lastFcmpl = 0;
|
||||
} else {
|
||||
if (not floatBranch(frame, ip, 4, true, a, b)) {
|
||||
frame->pushInt
|
||||
(c->call
|
||||
(c->constant
|
||||
@ -3473,11 +3562,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::Operand* b = frame->popObject();
|
||||
Compiler::Operand* target = frame->machineIp(newIp);
|
||||
|
||||
c->cmp(BytesPerWord, a, b);
|
||||
if (instruction == if_acmpeq) {
|
||||
c->je(target);
|
||||
c->jumpIfEqual(BytesPerWord, a, btarget);
|
||||
} else {
|
||||
c->jne(target);
|
||||
c->jumpIfNotEqual(BytesPerWord, a, btarget);
|
||||
}
|
||||
|
||||
saveStateAndCompile(t, frame, newIp);
|
||||
@ -3498,26 +3586,27 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::Operand* b = frame->popInt();
|
||||
Compiler::Operand* target = frame->machineIp(newIp);
|
||||
|
||||
c->cmp(4, a, b);
|
||||
switch (instruction) {
|
||||
case if_icmpeq:
|
||||
c->je(target);
|
||||
c->jumpIfEqual(4, a, b, target);
|
||||
break;
|
||||
case if_icmpne:
|
||||
c->jne(target);
|
||||
c->jumpIfNotEqual(4, a, b, target);
|
||||
break;
|
||||
case if_icmpgt:
|
||||
c->jg(target);
|
||||
c->jumpIfGreater(4, a, b, target);
|
||||
break;
|
||||
case if_icmpge:
|
||||
c->jge(target);
|
||||
c->jumpIfGreaterOrEqual(4, a, b, target);
|
||||
break;
|
||||
case if_icmplt:
|
||||
c->jl(target);
|
||||
c->jumpIfLess(4, a, b, target);
|
||||
break;
|
||||
case if_icmple:
|
||||
c->jle(target);
|
||||
c->jumpIfLessOrEqual(4, a, b, target);
|
||||
break;
|
||||
default:
|
||||
abort(t);
|
||||
}
|
||||
|
||||
saveStateAndCompile(t, frame, newIp);
|
||||
@ -3537,67 +3626,30 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::Operand* target = frame->machineIp(newIp);
|
||||
Compiler::Operand* cont = frame->machineIp(ip);
|
||||
|
||||
if (lastFcmpl != 1 and lastFcmpg != 1) {
|
||||
Compiler::Operand* a = frame->popInt();
|
||||
c->cmp(4, c->constant(0, Compiler::IntegerType), a);
|
||||
}
|
||||
Compiler::Operand* a = c->constant(0, Compiler::IntegerType);
|
||||
Compiler::Operand* b = frame->popInt();
|
||||
|
||||
switch (instruction) {
|
||||
case ifeq:
|
||||
if (lastFcmpl == 1 or lastFcmpg == 1) {
|
||||
c->fjuo(cont);
|
||||
c->fje(target);
|
||||
} else {
|
||||
c->je(target);
|
||||
}
|
||||
c->jumpIfEqual(4, a, b, target);
|
||||
break;
|
||||
case ifne:
|
||||
if (lastFcmpl == 1 or lastFcmpg == 1) {
|
||||
c->fjuo(cont);
|
||||
c->fjne(target);
|
||||
} else {
|
||||
c->jne(target);
|
||||
}
|
||||
c->jumpIfNotEqual(4, a, b, target);
|
||||
break;
|
||||
case ifgt:
|
||||
if (lastFcmpl == 1) {
|
||||
c->fjuo(cont);
|
||||
c->fjg(target);
|
||||
} else if (lastFcmpg == 1) {
|
||||
c->fjg(target);
|
||||
} else {
|
||||
c->jg(target);
|
||||
}
|
||||
c->jumpIfGreater(4, a, b, target);
|
||||
break;
|
||||
case ifge:
|
||||
if (lastFcmpl == 1) {
|
||||
c->fjuo(cont);
|
||||
c->fjge(target);
|
||||
} else if (lastFcmpg == 1) {
|
||||
c->fjge(target);
|
||||
} else {
|
||||
c->jge(target);
|
||||
}
|
||||
c->jumpIfGreaterOrEqual(4, a, b, target);
|
||||
break;
|
||||
case iflt:
|
||||
if (lastFcmpg == 1) {
|
||||
c->fjuo(cont);
|
||||
c->fjl(target);
|
||||
} else if (lastFcmpl == 1) {
|
||||
c->fjl(target);
|
||||
} else {
|
||||
c->jl(target);
|
||||
}
|
||||
c->jumpIfLess(4, a, b, target);
|
||||
break;
|
||||
case ifle:
|
||||
if(lastFcmpg == 1) {
|
||||
c->fjuo(cont);
|
||||
c->fjle(target);
|
||||
} else if (lastFcmpl == 1) {
|
||||
c->fjle(target);
|
||||
} else {
|
||||
c->jle(target);
|
||||
}
|
||||
c->jumpIfLessOrEqual(4, a, b, target);
|
||||
break;
|
||||
default:
|
||||
abort(t);
|
||||
}
|
||||
|
||||
saveStateAndCompile(t, frame, newIp);
|
||||
@ -3610,14 +3662,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
uint32_t newIp = (ip - 3) + offset;
|
||||
assert(t, newIp < codeLength(t, code));
|
||||
|
||||
Compiler::Operand* a = frame->popObject();
|
||||
Compiler::Operand* a = c->constant(0, Compiler::ObjectType);
|
||||
Compiler::Operand* b = frame->popObject();
|
||||
Compiler::Operand* target = frame->machineIp(newIp);
|
||||
|
||||
c->cmp(BytesPerWord, c->constant(0, Compiler::ObjectType), a);
|
||||
if (instruction == ifnull) {
|
||||
c->je(target);
|
||||
c->jumpIfEqual(BytesPerWord, a, btarget);
|
||||
} else {
|
||||
c->jne(target);
|
||||
c->jumpIfNotEqual(BytesPerWord, a, btarget);
|
||||
}
|
||||
|
||||
saveStateAndCompile(t, frame, newIp);
|
||||
@ -3971,7 +4023,15 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::Operand* a = frame->popLong();
|
||||
Compiler::Operand* b = frame->popLong();
|
||||
|
||||
frame->pushInt(c->lcmp(a, b));
|
||||
if (not integerBranch(frame, ip, 8, a, b)) {
|
||||
frame->pushInt
|
||||
(c->call
|
||||
(c->constant
|
||||
(getThunk(t, compareLongsThunk), Compiler::AddressType),
|
||||
0, 0, 4, Compiler::IntegerType, 4,
|
||||
static_cast<Compiler::Operand*>(0), a,
|
||||
static_cast<Compiler::Operand*>(0), b));
|
||||
}
|
||||
} break;
|
||||
|
||||
case lconst_0:
|
||||
@ -4522,15 +4582,15 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
|
||||
Compiler::Operand* key = frame->popInt();
|
||||
|
||||
c->cmp(4, c->constant(bottom, Compiler::IntegerType), key);
|
||||
c->jl(frame->machineIp(defaultIp));
|
||||
c->jumpIfLess(4, c->constant(bottom, Compiler::IntegerType), key,
|
||||
frame->machineIp(defaultIp));
|
||||
|
||||
c->save(1, key);
|
||||
|
||||
saveStateAndCompile(t, frame, defaultIp);
|
||||
|
||||
c->cmp(4, c->constant(top, Compiler::IntegerType), key);
|
||||
c->jg(frame->machineIp(defaultIp));
|
||||
c->jumpIfGreater(4, c->constant(top, Compiler::IntegerType), key,
|
||||
frame->machineIp(defaultIp));
|
||||
|
||||
c->save(1, key);
|
||||
|
||||
|
507
src/compiler.cpp
507
src/compiler.cpp
@ -66,13 +66,6 @@ apply(Context* c, TernaryOperation op,
|
||||
unsigned s2Size, Site* s2Low, Site* s2High,
|
||||
unsigned s3Size, Site* s3Low, Site* s3High);
|
||||
|
||||
enum ConstantCompare {
|
||||
CompareNone,
|
||||
CompareLess,
|
||||
CompareGreater,
|
||||
CompareEqual
|
||||
};
|
||||
|
||||
class Cell {
|
||||
public:
|
||||
Cell(Cell* next, void* value): next(next), value(value) { }
|
||||
@ -385,8 +378,7 @@ class Context {
|
||||
localFootprint(0),
|
||||
machineCodeSize(0),
|
||||
alignedFrameSize(0),
|
||||
availableGeneralRegisterCount(generalRegisterLimit - generalRegisterStart),
|
||||
constantCompare(CompareNone)
|
||||
availableGeneralRegisterCount(generalRegisterLimit - generalRegisterStart)
|
||||
{
|
||||
for (unsigned i = generalRegisterStart; i < generalRegisterLimit; ++i) {
|
||||
new (registerResources + i) RegisterResource(arch->reserved(i));
|
||||
@ -433,7 +425,6 @@ class Context {
|
||||
unsigned machineCodeSize;
|
||||
unsigned alignedFrameSize;
|
||||
unsigned availableGeneralRegisterCount;
|
||||
ConstantCompare constantCompare;
|
||||
};
|
||||
|
||||
unsigned
|
||||
@ -3459,82 +3450,6 @@ findConstantSite(Context* c, Value* v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
class CompareEvent: public Event {
|
||||
public:
|
||||
CompareEvent(Context* c, BinaryOperation type, unsigned size, Value* first,
|
||||
Value* second, const SiteMask& firstMask,
|
||||
const SiteMask& secondMask):
|
||||
Event(c), type(type), size(size), first(first), second(second)
|
||||
{
|
||||
assert(c, type != FloatCompare or
|
||||
(first->type == ValueFloat and first->type == ValueFloat));
|
||||
|
||||
addReads(c, this, first, size, firstMask, firstMask);
|
||||
addReads(c, this, second, size, secondMask, secondMask);
|
||||
}
|
||||
|
||||
virtual const char* name() {
|
||||
return "CompareEvent";
|
||||
}
|
||||
|
||||
virtual void compile(Context* c) {
|
||||
ConstantSite* firstConstant = findConstantSite(c, first);
|
||||
ConstantSite* secondConstant = findConstantSite(c, second);
|
||||
|
||||
if (firstConstant and secondConstant) {
|
||||
int64_t d = firstConstant->value->value()
|
||||
- secondConstant->value->value();
|
||||
|
||||
if (d < 0) {
|
||||
c->constantCompare = CompareLess;
|
||||
} else if (d > 0) {
|
||||
c->constantCompare = CompareGreater;
|
||||
} else {
|
||||
c->constantCompare = CompareEqual;
|
||||
}
|
||||
} else {
|
||||
c->constantCompare = CompareNone;
|
||||
|
||||
apply(c, type, size, first->source, first->source,
|
||||
size, second->source, second->source);
|
||||
}
|
||||
|
||||
for (Read* r = reads; r; r = r->eventNext) {
|
||||
popRead(c, this, r->value);
|
||||
}
|
||||
}
|
||||
|
||||
BinaryOperation type;
|
||||
unsigned size;
|
||||
Value* first;
|
||||
Value* second;
|
||||
};
|
||||
|
||||
void
|
||||
appendCompare(Context* c, BinaryOperation op, unsigned size, Value* first,
|
||||
Value* second)
|
||||
{
|
||||
bool thunk;
|
||||
uint8_t firstTypeMask;
|
||||
uint64_t firstRegisterMask;
|
||||
uint8_t secondTypeMask;
|
||||
uint64_t secondRegisterMask;
|
||||
|
||||
c->arch->planSource
|
||||
(op, size, &firstTypeMask, &firstRegisterMask, size, &thunk);
|
||||
|
||||
assert(c, not thunk); // todo
|
||||
|
||||
c->arch->planDestination
|
||||
(op, size, 0, 0, size, &secondTypeMask, &secondRegisterMask);
|
||||
|
||||
append(c, new (c->zone->allocate(sizeof(CompareEvent)))
|
||||
CompareEvent
|
||||
(c, op, size, first, second,
|
||||
SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex),
|
||||
SiteMask(secondTypeMask, secondRegisterMask, AnyFrameIndex)));
|
||||
}
|
||||
|
||||
void
|
||||
preserve(Context* c, Value* v, Site* s, Read* r)
|
||||
{
|
||||
@ -3576,12 +3491,6 @@ getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask)
|
||||
return s;
|
||||
}
|
||||
|
||||
Site*
|
||||
source(Value* v, Site* site)
|
||||
{
|
||||
return v ? v->source : site;
|
||||
}
|
||||
|
||||
void
|
||||
freezeSource(Context* c, unsigned size, Value* v)
|
||||
{
|
||||
@ -3674,8 +3583,8 @@ class CombineEvent: public Event {
|
||||
|
||||
// fprintf(stderr, "combine %p and %p into %p\n", first, second, result);
|
||||
apply(c, type,
|
||||
firstSize, first->source, source(first->next, first->source),
|
||||
secondSize, second->source, source(second->next, second->source),
|
||||
firstSize, first->source, first->next->source),
|
||||
secondSize, second->source, second->next->source),
|
||||
resultSize, low, high);
|
||||
|
||||
thawSource(c, firstSize, first);
|
||||
@ -4095,8 +4004,7 @@ class TranslateEvent: public Event {
|
||||
? getTarget(c, value->next, result->next, resultHighMask)
|
||||
: low);
|
||||
|
||||
apply(c, type,
|
||||
valueSize, value->source, source(value->next, value->source),
|
||||
apply(c, type, valueSize, value->source, value->next->source),
|
||||
resultSize, low, high);
|
||||
|
||||
for (Read* r = reads; r; r = r->eventNext) {
|
||||
@ -4264,20 +4172,96 @@ appendMemory(Context* c, Value* base, int displacement, Value* index,
|
||||
MemoryEvent(c, base, displacement, index, scale, result));
|
||||
}
|
||||
|
||||
double
|
||||
asFloat(unsigned size, int64_t v)
|
||||
{
|
||||
if (size == 4) {
|
||||
return bitsToFloat(v);
|
||||
} else {
|
||||
return bitsToDouble(v);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
unordered(double a, double b)
|
||||
{
|
||||
return not (a >= b or a < b);
|
||||
}
|
||||
|
||||
bool
|
||||
shouldJump(TernaryOperation type, unsigned size, int64_t a, int64_t b)
|
||||
{
|
||||
switch (type) {
|
||||
case JumpIfEqual:
|
||||
return a == b;
|
||||
|
||||
case JumpIfNotEqual:
|
||||
return a != b;
|
||||
|
||||
case JumpIfLess:
|
||||
return a < b;
|
||||
|
||||
case JumpIfGreater:
|
||||
return a > b;
|
||||
|
||||
case JumpIfLessOrEqual:
|
||||
return a <= b;
|
||||
|
||||
case JumpIfGreaterOrEqual:
|
||||
return a >= b;
|
||||
|
||||
case JumpIfFloatEqual:
|
||||
return asFloat(size, a) == asFloat(size, b);
|
||||
|
||||
case JumpIfFloatNotEqual:
|
||||
return asFloat(size, a) != asFloat(size, b);
|
||||
|
||||
case JumpIfFloatLess:
|
||||
return asFloat(size, a) < asFloat(size, b);
|
||||
|
||||
case JumpIfFloatGreater:
|
||||
return asFloat(size, a) > asFloat(size, b);
|
||||
|
||||
case JumpIfFloatLessOrEqual:
|
||||
return asFloat(size, a) <= asFloat(size, b);
|
||||
|
||||
case JumpIfFloatGreaterOrEqual:
|
||||
return asFloat(size, a) >= asFloat(size, b);
|
||||
|
||||
case JumpIfFloatLessOrUnordered:
|
||||
return asFloat(size, a) < asFloat(size, b)
|
||||
or unordered(asFloat(size, a), asFloat(size, b));
|
||||
|
||||
case JumpIfFloatGreaterOrUnordered:
|
||||
return asFloat(size, a) > asFloat(size, b)
|
||||
or unordered(asFloat(size, a), asFloat(size, b));
|
||||
|
||||
case JumpIfFloatLessOrEqualOrUnordered:
|
||||
return asFloat(size, a) <= asFloat(size, b)
|
||||
or unordered(asFloat(size, a), asFloat(size, b));
|
||||
|
||||
case JumpIfFloatGreaterOrEqualOrUnordered:
|
||||
return asFloat(size, a) >= asFloat(size, b)
|
||||
or unordered(asFloat(size, a), asFloat(size, b));
|
||||
|
||||
default:
|
||||
jump = false;
|
||||
}
|
||||
}
|
||||
|
||||
class BranchEvent: public Event {
|
||||
public:
|
||||
BranchEvent(Context* c, UnaryOperation type, Value* address, bool exit):
|
||||
Event(c), type(type), address(address), exit(exit)
|
||||
BranchEvent(Context* c, TernaryOperation type, unsigned size,
|
||||
Value* first, Value* second, Value* address, bool exit,
|
||||
const SiteMask& firstLowMask,
|
||||
const SiteMask& firstHighMask,
|
||||
const SiteMask& secondLowMask,
|
||||
const SiteMask& secondHighMask):
|
||||
Event(c), type(type), size(size), first(first), second(second),
|
||||
address(address), exit(exit)
|
||||
{
|
||||
bool thunk;
|
||||
uint8_t typeMask;
|
||||
uint64_t registerMask;
|
||||
|
||||
c->arch->plan(type, BytesPerWord, &typeMask, ®isterMask, &thunk);
|
||||
|
||||
assert(c, not thunk);
|
||||
|
||||
addRead(c, this, address, SiteMask(typeMask, registerMask, AnyFrameIndex));
|
||||
addReads(c, this, first, firstSize, firstLowMask, firstHighMask);
|
||||
addReads(c, this, second, secondSize, secondLowMask, secondHighMask);
|
||||
}
|
||||
|
||||
virtual const char* name() {
|
||||
@ -4285,67 +4269,27 @@ class BranchEvent: public Event {
|
||||
}
|
||||
|
||||
virtual void compile(Context* c) {
|
||||
bool jump;
|
||||
UnaryOperation type = this->type;
|
||||
if (type != Jump) {
|
||||
switch (c->constantCompare) {
|
||||
case CompareLess:
|
||||
switch (type) {
|
||||
case JumpIfLess:
|
||||
case JumpIfLessOrEqual:
|
||||
case JumpIfNotEqual:
|
||||
jump = true;
|
||||
type = Jump;
|
||||
break;
|
||||
ConstantSite* firstConstant = findConstantSite(c, first);
|
||||
ConstantSite* secondConstant = findConstantSite(c, second);
|
||||
|
||||
default:
|
||||
jump = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case CompareGreater:
|
||||
switch (type) {
|
||||
case JumpIfGreater:
|
||||
case JumpIfGreaterOrEqual:
|
||||
case JumpIfNotEqual:
|
||||
jump = true;
|
||||
type = Jump;
|
||||
break;
|
||||
|
||||
default:
|
||||
jump = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case CompareEqual:
|
||||
switch (type) {
|
||||
case JumpIfEqual:
|
||||
case JumpIfLessOrEqual:
|
||||
case JumpIfGreaterOrEqual:
|
||||
jump = true;
|
||||
type = Jump;
|
||||
break;
|
||||
|
||||
default:
|
||||
jump = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case CompareNone:
|
||||
jump = true;
|
||||
break;
|
||||
|
||||
default: abort(c);
|
||||
if (not unreachable(this)) {
|
||||
if (firstConstant and secondConstant) {
|
||||
if (shouldJump(type, firstConstant->value->value(),
|
||||
secondConstant->value->value())
|
||||
and reachable)
|
||||
{
|
||||
apply(c, Jump, BytesPerWord, address->source, address->source);
|
||||
}
|
||||
} else {
|
||||
apply(c, type, size, first->source, first->next->source,
|
||||
size, second->source, second->next->sourcem
|
||||
BytesPerWord, address->source, address->source);
|
||||
}
|
||||
} else {
|
||||
jump = true;
|
||||
}
|
||||
|
||||
if (jump and not unreachable(this)) {
|
||||
apply(c, type, BytesPerWord, address->source, address->source);
|
||||
for (Read* r = reads; r; r = r->eventNext) {
|
||||
popRead(c, this, r->value);
|
||||
}
|
||||
|
||||
popRead(c, this, address);
|
||||
}
|
||||
|
||||
virtual bool isBranch() { return true; }
|
||||
@ -4355,10 +4299,57 @@ class BranchEvent: public Event {
|
||||
}
|
||||
|
||||
UnaryOperation type;
|
||||
unsigned size;
|
||||
Value* first;
|
||||
Value* second;
|
||||
Value* address;
|
||||
bool exit;
|
||||
};
|
||||
|
||||
void
|
||||
appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first,
|
||||
Value* second, Value* address, bool exit = false)
|
||||
{
|
||||
bool thunk;
|
||||
uint8_t firstTypeMask;
|
||||
uint64_t firstRegisterMask;
|
||||
uint8_t secondTypeMask;
|
||||
uint64_t secondRegisterMask;
|
||||
|
||||
c->arch->planSource(type, size, &firstTypeMask, &firstRegisterMask,
|
||||
size, &secondTypeMask, &secondRegisterMask,
|
||||
resultSize, &thunk);
|
||||
|
||||
if (thunk) {
|
||||
Stack* oldStack = c->stack;
|
||||
|
||||
local::push(c, ceiling(size, BytesPerWord), second, false);
|
||||
local::push(c, ceiling(size, BytesPerWord), first, false);
|
||||
|
||||
Stack* argumentStack = c->stack;
|
||||
c->stack = oldStack;
|
||||
|
||||
Value* result = value(&c, ValueGeneral);
|
||||
appendCall
|
||||
(c, value
|
||||
(c, ValueGeneral, constantSite(c, c->client->getThunk(type, size, 4))),
|
||||
0, 0, result, resultSize, argumentStack,
|
||||
ceiling(size, BytesPerWord) * 2, 0);
|
||||
|
||||
appendBranch(c, JumpIfEqual, 4, value(c, ValueGeneral, constantSite(c, 0)),
|
||||
result, address);
|
||||
} else {
|
||||
append
|
||||
(c, new (c->zone->allocate(sizeof(BranchEvent)))
|
||||
BranchEvent
|
||||
(c, type, size, first, second, address, exit,
|
||||
SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex),
|
||||
SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex),
|
||||
SiteMask(secondTypeMask, secondRegisterMask, AnyFrameIndex),
|
||||
SiteMask(secondTypeMask, secondRegisterMask >> 32, AnyFrameIndex)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
appendBranch(Context* c, UnaryOperation type, Value* address,
|
||||
bool exit = false)
|
||||
@ -4396,11 +4387,10 @@ class BoundsCheckEvent: public Event {
|
||||
outOfBoundsPromise = codePromise(c, static_cast<Promise*>(0));
|
||||
|
||||
Site* zero = constantSite(c, resolved(c, 0));
|
||||
apply(c, Compare, 4, zero, zero, 4, index->source, index->source);
|
||||
|
||||
Assembler::Constant outOfBoundsConstant(outOfBoundsPromise);
|
||||
a->apply
|
||||
(JumpIfLess, BytesPerWord, ConstantOperand, &outOfBoundsConstant);
|
||||
(JumpIfLess, 4, zero, zero, 4, index->source, index->source,
|
||||
BytesPerWord, ConstantOperand, &outOfBoundsConstant);
|
||||
}
|
||||
|
||||
assert(c, object->source->type(c) == RegisterOperand);
|
||||
@ -4408,10 +4398,9 @@ class BoundsCheckEvent: public Event {
|
||||
lengthOffset, NoRegister, 1);
|
||||
length.acquired = true;
|
||||
|
||||
apply(c, Compare, 4, index->source, index->source, 4, &length, &length);
|
||||
|
||||
Assembler::Constant nextConstant(nextPromise);
|
||||
a->apply(JumpIfGreater, BytesPerWord, ConstantOperand, &nextConstant);
|
||||
a->apply(JumpIfGreater, 4, index->source, index->source, 4, &length,
|
||||
&length, BytesPerWord, ConstantOperand, &nextConstant);
|
||||
|
||||
if (constant == 0) {
|
||||
outOfBoundsPromise->offset = a->offset();
|
||||
@ -5953,88 +5942,176 @@ class MyCompiler: public Compiler {
|
||||
return dst;
|
||||
}
|
||||
|
||||
virtual Operand* lcmp(Operand* a, Operand* b) {
|
||||
virtual void jumpIfEqual(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral
|
||||
and static_cast<Value*>(b)->type == ValueGeneral);
|
||||
Value* result = value(&c, ValueGeneral);
|
||||
appendCombine(&c, LongCompare, 8, static_cast<Value*>(a),
|
||||
8, static_cast<Value*>(b), 8, result);
|
||||
return result;
|
||||
|
||||
appendBranch(&c, JumpIfEqual, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void cmp(unsigned size, Operand* a, Operand* b) {
|
||||
virtual void jumpIfNotEqual(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral
|
||||
and static_cast<Value*>(b)->type == ValueGeneral);
|
||||
appendCompare(&c, Compare, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b));
|
||||
|
||||
appendBranch(&c, JumpIfNotEqual, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void fcmp(unsigned size, Operand* a, Operand* b) {
|
||||
virtual void jumpIfLess(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral
|
||||
and static_cast<Value*>(b)->type == ValueGeneral);
|
||||
|
||||
appendBranch(&c, JumpIfLess, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void jumpIfGreater(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral
|
||||
and static_cast<Value*>(b)->type == ValueGeneral);
|
||||
|
||||
appendBranch(&c, JumpIfGreater, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void jumpIfLessOrEqual(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral
|
||||
and static_cast<Value*>(b)->type == ValueGeneral);
|
||||
|
||||
appendBranch(&c, JumpIfLessOrEqual, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void jumpIfGreaterOrEqual(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral
|
||||
and static_cast<Value*>(b)->type == ValueGeneral);
|
||||
|
||||
appendBranch(&c, JumpIfGreaterOrEqual, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void jumpIfFloatEqual(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueFloat
|
||||
and static_cast<Value*>(b)->type == ValueFloat);
|
||||
appendCompare(&c, FloatCompare, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b));
|
||||
}
|
||||
|
||||
|
||||
virtual void jl(Operand* address) {
|
||||
appendBranch(&c, JumpIfLess, static_cast<Value*>(address));
|
||||
appendBranch(&c, JumpIfFloatEqual, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void jg(Operand* address) {
|
||||
appendBranch(&c, JumpIfGreater, static_cast<Value*>(address));
|
||||
virtual void jumpIfFloatNotEqual(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueFloat
|
||||
and static_cast<Value*>(b)->type == ValueFloat);
|
||||
|
||||
appendBranch(&c, JumpIfFloatNotEqual, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void jle(Operand* address) {
|
||||
appendBranch(&c, JumpIfLessOrEqual, static_cast<Value*>(address));
|
||||
virtual void jumpIfFloatLess(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueFloat
|
||||
and static_cast<Value*>(b)->type == ValueFloat);
|
||||
|
||||
appendBranch(&c, JumpIfFloatLess, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void jge(Operand* address) {
|
||||
appendBranch(&c, JumpIfGreaterOrEqual, static_cast<Value*>(address));
|
||||
virtual void jumpIfFloatGreater(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueFloat
|
||||
and static_cast<Value*>(b)->type == ValueFloat);
|
||||
|
||||
appendBranch(&c, JumpIfFloatGreater, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void je(Operand* address) {
|
||||
appendBranch(&c, JumpIfEqual, static_cast<Value*>(address));
|
||||
virtual void jumpIfFloatLessOrEqual(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueFloat
|
||||
and static_cast<Value*>(b)->type == ValueFloat);
|
||||
|
||||
appendBranch(&c, JumpIfFloatLessOrEqual, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void jne(Operand* address) {
|
||||
appendBranch(&c, JumpIfNotEqual, static_cast<Value*>(address));
|
||||
virtual void jumpIfFloatGreaterOrEqual(unsigned size, Operand* a, Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueFloat
|
||||
and static_cast<Value*>(b)->type == ValueFloat);
|
||||
|
||||
appendBranch(&c, JumpIfFloatGreaterOrEqual, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void fjl(Operand* address) {
|
||||
appendBranch(&c, JumpIfFloatLess, static_cast<Value*>(address));
|
||||
virtual void jumpIfFloatLessOrUnordered(unsigned size, Operand* a,
|
||||
Operand* b, Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueFloat
|
||||
and static_cast<Value*>(b)->type == ValueFloat);
|
||||
|
||||
appendBranch(&c, JumpIfFloatLessOrUnordered, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void fjg(Operand* address) {
|
||||
appendBranch(&c, JumpIfFloatGreater, static_cast<Value*>(address));
|
||||
virtual void jumpIfFloatGreaterOrUnordered(unsigned size, Operand* a,
|
||||
Operand* b, Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueFloat
|
||||
and static_cast<Value*>(b)->type == ValueFloat);
|
||||
|
||||
appendBranch(&c, JumpIfFloatGreaterOrUnordered, size,
|
||||
static_cast<Value*>(a), static_cast<Value*>(b),
|
||||
static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void fjle(Operand* address) {
|
||||
appendBranch(&c, JumpIfFloatLessOrEqual, static_cast<Value*>(address));
|
||||
virtual void jumpIfFloatLessOrEqualOrUnordered(unsigned size, Operand* a,
|
||||
Operand* b, Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueFloat
|
||||
and static_cast<Value*>(b)->type == ValueFloat);
|
||||
|
||||
appendBranch(&c, JumpIfFloatLessOrEqualOrUnordered, size,
|
||||
static_cast<Value*>(a), static_cast<Value*>(b),
|
||||
static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void fjge(Operand* address) {
|
||||
appendBranch(&c, JumpIfFloatGreaterOrEqual, static_cast<Value*>(address));
|
||||
}
|
||||
virtual void jumpIfFloatGreaterOrEqualOrUnordered(unsigned size, Operand* a,
|
||||
Operand* b,
|
||||
Operand* address)
|
||||
{
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueFloat
|
||||
and static_cast<Value*>(b)->type == ValueFloat);
|
||||
|
||||
virtual void fje(Operand* address) {
|
||||
appendBranch(&c, JumpIfFloatEqual, static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void fjne(Operand* address) {
|
||||
appendBranch(&c, JumpIfFloatNotEqual, static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void fjuo(Operand* address) {
|
||||
appendBranch(&c, JumpIfFloatUnordered, static_cast<Value*>(address));
|
||||
appendBranch(&c, JumpIfFloatGreaterOrEqualOrUnordered, size,
|
||||
static_cast<Value*>(a), static_cast<Value*>(b),
|
||||
static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void jmp(Operand* address) {
|
||||
appendBranch(&c, Jump, static_cast<Value*>(address));
|
||||
appendBranch(&c, Jump, 0, 0, 0, static_cast<Value*>(address));
|
||||
}
|
||||
|
||||
virtual void exit(Operand* address) {
|
||||
appendBranch(&c, Jump, static_cast<Value*>(address), true);
|
||||
appendBranch(&c, Jump, 0, 0, 0, static_cast<Value*>(address), true);
|
||||
}
|
||||
|
||||
virtual Operand* add(unsigned size, Operand* a, Operand* b) {
|
||||
|
@ -120,22 +120,41 @@ class Compiler {
|
||||
unsigned dstSize) = 0;
|
||||
virtual Operand* loadz(unsigned size, unsigned srcSelectSize, Operand* src,
|
||||
unsigned dstSize) = 0;
|
||||
virtual Operand* lcmp(Operand* a, Operand* b) = 0;
|
||||
virtual void cmp(unsigned size, Operand* a, Operand* b) = 0;
|
||||
virtual void fcmp(unsigned size, Operand* a, Operand* b) = 0;
|
||||
virtual void jl(Operand* address) = 0;
|
||||
virtual void jg(Operand* address) = 0;
|
||||
virtual void jle(Operand* address) = 0;
|
||||
virtual void jge(Operand* address) = 0;
|
||||
virtual void je(Operand* address) = 0;
|
||||
virtual void jne(Operand* address) = 0;
|
||||
virtual void fjl(Operand* address) = 0;
|
||||
virtual void fjg(Operand* address) = 0;
|
||||
virtual void fjle(Operand* address) = 0;
|
||||
virtual void fjge(Operand* address) = 0;
|
||||
virtual void fje(Operand* address) = 0;
|
||||
virtual void fjne(Operand* address) = 0;
|
||||
virtual void fjuo(Operand* address) = 0;
|
||||
|
||||
virtual void jumpIfEqual
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfNotEqual
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfLess
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfGreater
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfLessOrEqual
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfGreaterOrEqual
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
|
||||
virtual void jumpIfFloatEqual
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfFloatNotEqual
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfFloatLess
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfFloatGreater
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfFloatLessOrEqual
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfFloatGreaterOrEqual
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfFloatLessOrUnordered
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfFloatGreaterOrUnordered
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfFloatLessOrEqualOrUnordered
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
virtual void jumpIfFloatGreaterOrEqualOrUnordered
|
||||
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
|
||||
|
||||
virtual void jmp(Operand* address) = 0;
|
||||
virtual void exit(Operand* address) = 0;
|
||||
virtual Operand* add(unsigned size, Operand* a, Operand* b) = 0;
|
||||
|
@ -1847,10 +1847,6 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
return NoTernaryOperation;
|
||||
}
|
||||
|
||||
virtual bool supportsFloatCompare(unsigned) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool alwaysCondensed(BinaryOperation) {
|
||||
return false;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ THUNK(compareDoublesG)
|
||||
THUNK(compareDoublesL)
|
||||
THUNK(compareFloatsG)
|
||||
THUNK(compareFloatsL)
|
||||
THUNK(compareLongs)
|
||||
THUNK(addDouble)
|
||||
THUNK(subtractDouble)
|
||||
THUNK(multiplyDouble)
|
||||
|
@ -2713,10 +2713,6 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool supportsFloatCompare(unsigned) {
|
||||
return supportsSSE();
|
||||
}
|
||||
|
||||
virtual bool alwaysCondensed(BinaryOperation op)
|
||||
{
|
||||
switch(op) {
|
||||
|
Loading…
Reference in New Issue
Block a user