mirror of
https://github.com/corda/corda.git
synced 2025-02-02 09:18:13 +00:00
support encoding instructions with indexed and scaled memory offsets
This commit is contained in:
parent
ec8fc80ebe
commit
b3918a0d7d
@ -118,7 +118,6 @@ nextPowerOfTwo(unsigned n)
|
|||||||
inline unsigned
|
inline unsigned
|
||||||
log(unsigned n)
|
log(unsigned n)
|
||||||
{
|
{
|
||||||
if (n < 3) return 1;
|
|
||||||
unsigned r = 0;
|
unsigned r = 0;
|
||||||
for (unsigned i = 1; i < n; ++r) i <<= 1;
|
for (unsigned i = 1; i < n; ++r) i <<= 1;
|
||||||
return r;
|
return r;
|
||||||
|
107
src/compiler.cpp
107
src/compiler.cpp
@ -255,10 +255,7 @@ class MemoryOperand: public MyOperand {
|
|||||||
displacement(displacement),
|
displacement(displacement),
|
||||||
index(index),
|
index(index),
|
||||||
scale(scale)
|
scale(scale)
|
||||||
{
|
{ }
|
||||||
assert(static_cast<System*>(0), index == 0); // todo
|
|
||||||
assert(static_cast<System*>(0), scale == 1); // todo
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Register asRegister(Context*);
|
virtual Register asRegister(Context*);
|
||||||
|
|
||||||
@ -863,36 +860,51 @@ rex(Context* c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
encode(Context* c, uint8_t instruction, uint8_t zeroPrefix,
|
encode(Context* c, uint8_t instruction, int a, Register b,
|
||||||
uint8_t bytePrefix, uint8_t wordPrefix,
|
int32_t displacement, int index, unsigned scale)
|
||||||
Register a, Register b, int32_t offset)
|
|
||||||
{
|
{
|
||||||
c->code.append(instruction);
|
c->code.append(instruction);
|
||||||
|
|
||||||
uint8_t prefix;
|
uint8_t width;
|
||||||
if (offset == 0 and b != rbp) {
|
if (displacement == 0 and b != rbp) {
|
||||||
prefix = zeroPrefix;
|
width = 0;
|
||||||
} else if (isInt8(offset)) {
|
} else if (isInt8(displacement)) {
|
||||||
prefix = bytePrefix;
|
width = 0x40;
|
||||||
} else {
|
} else {
|
||||||
prefix = wordPrefix;
|
width = 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->code.append(prefix | (a << 3) | b);
|
if (index == -1) {
|
||||||
|
c->code.append(width | (a << 3) | b);
|
||||||
if (b == rsp) {
|
if (b == rsp) {
|
||||||
c->code.append(0x24);
|
c->code.append(0x24);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(c, b != rsp);
|
||||||
|
c->code.append(width | (a << 3) | 4);
|
||||||
|
c->code.append((log(scale) << 6) | (index << 3) | b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == 0 and b != rbp) {
|
if (displacement == 0 and b != rbp) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} else if (isInt8(offset)) {
|
} else if (isInt8(displacement)) {
|
||||||
c->code.append(offset);
|
c->code.append(displacement);
|
||||||
} else {
|
} else {
|
||||||
c->code.append4(offset);
|
c->code.append4(displacement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
encode(Context* c, uint8_t instruction, int a, MemoryOperand* b, bool rex)
|
||||||
|
{
|
||||||
|
Register r = b->base->asRegister(c);
|
||||||
|
int index = b->index ? b->index->asRegister(c) : -1;
|
||||||
|
if (rex) {
|
||||||
|
::rex(c);
|
||||||
|
}
|
||||||
|
encode(c, instruction, a, r, b->displacement, index, b->scale);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RegisterOperand::apply(Context* c, Operation operation)
|
RegisterOperand::apply(Context* c, Operation operation)
|
||||||
{
|
{
|
||||||
@ -1017,15 +1029,11 @@ RegisterOperand::accept(Context* c, Operation operation,
|
|||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case cmp: {
|
case cmp: {
|
||||||
Register r = operand->base->asRegister(c);
|
encode(c, 0x3b, value, operand, true);
|
||||||
rex(c);
|
|
||||||
encode(c, 0x3b, 0, 0x40, 0x80, value, r, operand->displacement);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mov: {
|
case mov: {
|
||||||
Register r = operand->base->asRegister(c);
|
encode(c, 0x8b, value, operand, true);
|
||||||
rex(c);
|
|
||||||
encode(c, 0x8b, 0, 0x40, 0x80, value, r, operand->displacement);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
@ -1038,27 +1046,24 @@ RegisterOperand::accept(Context* c, Operation operation,
|
|||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case mov: {
|
case mov: {
|
||||||
Register r = operand->base->asRegister(c);
|
|
||||||
|
|
||||||
switch (selection) {
|
switch (selection) {
|
||||||
case S1Selection:
|
case S1Selection:
|
||||||
c->code.append(0x0f);
|
c->code.append(0x0f);
|
||||||
encode(c, 0xbe, 0, 0x40, 0x80, value, r, operand->displacement);
|
encode(c, 0xbe, value, operand, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S2Selection:
|
case S2Selection:
|
||||||
c->code.append(0x0f);
|
c->code.append(0x0f);
|
||||||
encode(c, 0xbf, 0, 0x40, 0x80, value, r, operand->displacement);
|
encode(c, 0xbf, value, operand, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Z2Selection:
|
case Z2Selection:
|
||||||
c->code.append(0x0f);
|
c->code.append(0x0f);
|
||||||
encode(c, 0xb7, 0, 0x40, 0x80, value, r, operand->displacement);
|
encode(c, 0xb7, value, operand, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S4Selection:
|
case S4Selection:
|
||||||
rex(c);
|
encode(c, 0x63, value, operand, true);
|
||||||
encode(c, 0x63, 0, 0x40, 0x80, value, r, operand->displacement);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
@ -1254,15 +1259,19 @@ MemoryOperand::apply(Context* c, Operation operation)
|
|||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case call:
|
case call:
|
||||||
encode(c, 0xff, 0x10, 0x50, 0x90, rax, base->asRegister(c), displacement);
|
encode(c, 0xff, 2, this, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case neg:
|
||||||
|
encode(c, 0xf7, 2, this, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case pop:
|
case pop:
|
||||||
encode(c, 0x8f, 0, 0x40, 0x80, rax, base->asRegister(c), displacement);
|
encode(c, 0x8f, 0, this, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case push:
|
case push:
|
||||||
encode(c, 0xff, 0x30, 0x70, 0xb0, rax, base->asRegister(c), displacement);
|
encode(c, 0xff, 6, this, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
@ -1290,21 +1299,19 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case add: {
|
case add: {
|
||||||
Register r = base->asRegister(c);
|
encode(c, 0x01, operand->value, this, true);
|
||||||
rex(c);
|
|
||||||
encode(c, 0x01, 0, 0x40, 0x80, operand->value, r, displacement);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
// case div: {
|
||||||
|
// // todo
|
||||||
|
// } break;
|
||||||
|
|
||||||
case mov: {
|
case mov: {
|
||||||
Register r = base->asRegister(c);
|
encode(c, 0x89, operand->value, this, true);
|
||||||
rex(c);
|
|
||||||
encode(c, 0x89, 0, 0x40, 0x80, operand->value, r, displacement);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case sub: {
|
case sub: {
|
||||||
Register r = base->asRegister(c);
|
encode(c, 0x29, operand->value, this, true);
|
||||||
rex(c);
|
|
||||||
encode(c, 0x29, 0, 0x40, 0x80, operand->value, r, displacement);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
@ -1317,11 +1324,9 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case add: {
|
case add: {
|
||||||
Register r = base->asRegister(c);
|
|
||||||
unsigned i = (isInt8(operand->value) ? 0x83 : 0x81);
|
unsigned i = (isInt8(operand->value) ? 0x83 : 0x81);
|
||||||
|
|
||||||
rex(c);
|
encode(c, i, 0, this, true);
|
||||||
encode(c, i, 0, 0x40, 0x80, rax, r, displacement);
|
|
||||||
if (isInt8(operand->value)) {
|
if (isInt8(operand->value)) {
|
||||||
c->code.append(operand->value);
|
c->code.append(operand->value);
|
||||||
} else if (isInt32(operand->value)) {
|
} else if (isInt32(operand->value)) {
|
||||||
@ -1334,9 +1339,7 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
case mov: {
|
case mov: {
|
||||||
assert(c, isInt32(operand->value)); // todo
|
assert(c, isInt32(operand->value)); // todo
|
||||||
|
|
||||||
Register r = base->asRegister(c);
|
encode(c, 0xc7, 0, this, true);
|
||||||
rex(c);
|
|
||||||
encode(c, 0xc7, 0, 0x40, 0x80, rax, r, displacement);
|
|
||||||
c->code.append4(operand->value);
|
c->code.append4(operand->value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -464,10 +464,10 @@ class Context {
|
|||||||
system(system),
|
system(system),
|
||||||
client(client),
|
client(client),
|
||||||
|
|
||||||
ageMap(&gen1, log(TenureThreshold), 1, 0, false),
|
ageMap(&gen1, max(1, log(TenureThreshold)), 1, 0, false),
|
||||||
gen1(this, &ageMap, 0, 0),
|
gen1(this, &ageMap, 0, 0),
|
||||||
|
|
||||||
nextAgeMap(&nextGen1, log(TenureThreshold), 1, 0, false),
|
nextAgeMap(&nextGen1, max(1, log(TenureThreshold)), 1, 0, false),
|
||||||
nextGen1(this, &nextAgeMap, 0, 0),
|
nextGen1(this, &nextAgeMap, 0, 0),
|
||||||
|
|
||||||
pointerMap(&gen2, 1, 1, 0, true),
|
pointerMap(&gen2, 1, 1, 0, true),
|
||||||
@ -589,7 +589,7 @@ inline void
|
|||||||
initNextGen1(Context* c, unsigned footprint)
|
initNextGen1(Context* c, unsigned footprint)
|
||||||
{
|
{
|
||||||
new (&(c->nextAgeMap)) Segment::Map
|
new (&(c->nextAgeMap)) Segment::Map
|
||||||
(&(c->nextGen1), log(TenureThreshold), 1, 0, false);
|
(&(c->nextGen1), max(1, log(TenureThreshold)), 1, 0, false);
|
||||||
|
|
||||||
unsigned minimum
|
unsigned minimum
|
||||||
= (c->gen1.position() - c->tenureFootprint) + footprint + c->gen1padding;
|
= (c->gen1.position() - c->tenureFootprint) + footprint + c->gen1padding;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user