VM: Refactor instruction_operands.cpp/hpp to Factor style
parent
f6047832cb
commit
d3d1d3bb7a
|
@ -1,104 +1,99 @@
|
||||||
#include "master.hpp"
|
#include "master.hpp"
|
||||||
|
|
||||||
namespace factor
|
namespace factor {
|
||||||
{
|
|
||||||
|
|
||||||
instruction_operand::instruction_operand(relocation_entry rel_, code_block *compiled_, cell index_) :
|
instruction_operand::instruction_operand(relocation_entry rel_,
|
||||||
rel(rel_), compiled(compiled_), index(index_), pointer((cell)compiled_->entry_point() + rel_.rel_offset()) {}
|
code_block* compiled_, cell index_)
|
||||||
|
: rel(rel_),
|
||||||
|
compiled(compiled_),
|
||||||
|
index(index_),
|
||||||
|
pointer((cell) compiled_->entry_point() + rel_.rel_offset()) {}
|
||||||
|
|
||||||
/* Load a 32-bit value from a PowerPC LIS/ORI sequence */
|
/* Load a 32-bit value from a PowerPC LIS/ORI sequence */
|
||||||
fixnum instruction_operand::load_value_2_2()
|
fixnum instruction_operand::load_value_2_2() {
|
||||||
{
|
u32* ptr = (u32*)pointer;
|
||||||
u32 *ptr = (u32 *)pointer;
|
|
||||||
cell hi = (ptr[-2] & 0xffff);
|
cell hi = (ptr[-2] & 0xffff);
|
||||||
cell lo = (ptr[-1] & 0xffff);
|
cell lo = (ptr[-1] & 0xffff);
|
||||||
return hi << 16 | lo;
|
return hi << 16 | lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load a 64-bit value from a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence */
|
/* Load a 64-bit value from a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence */
|
||||||
fixnum instruction_operand::load_value_2_2_2_2()
|
fixnum instruction_operand::load_value_2_2_2_2() {
|
||||||
{
|
u32* ptr = (u32*)pointer;
|
||||||
u32 *ptr = (u32 *)pointer;
|
|
||||||
u64 hhi = (ptr[-5] & 0xffff);
|
u64 hhi = (ptr[-5] & 0xffff);
|
||||||
u64 hlo = (ptr[-4] & 0xffff);
|
u64 hlo = (ptr[-4] & 0xffff);
|
||||||
u64 lhi = (ptr[-2] & 0xffff);
|
u64 lhi = (ptr[-2] & 0xffff);
|
||||||
u64 llo = (ptr[-1] & 0xffff);
|
u64 llo = (ptr[-1] & 0xffff);
|
||||||
u64 val = hhi << 48 | hlo << 32 | lhi << 16 | llo;
|
u64 val = hhi << 48 | hlo << 32 | lhi << 16 | llo;
|
||||||
return (cell)val;
|
return (cell) val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load a value from a bitfield of a PowerPC instruction */
|
/* Load a value from a bitfield of a PowerPC instruction */
|
||||||
fixnum instruction_operand::load_value_masked(cell mask, cell bits, cell shift)
|
fixnum instruction_operand::load_value_masked(cell mask, cell bits,
|
||||||
{
|
cell shift) {
|
||||||
s32 *ptr = (s32 *)(pointer - sizeof(u32));
|
s32* ptr = (s32*)(pointer - sizeof(u32));
|
||||||
|
|
||||||
return (((*ptr & (s32)mask) << bits) >> bits) << shift;
|
return (((*ptr & (s32) mask) << bits) >> bits) << shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixnum instruction_operand::load_value(cell relative_to)
|
fixnum instruction_operand::load_value(cell relative_to) {
|
||||||
{
|
switch (rel.rel_class()) {
|
||||||
switch(rel.rel_class())
|
|
||||||
{
|
|
||||||
case RC_ABSOLUTE_CELL:
|
case RC_ABSOLUTE_CELL:
|
||||||
return *(cell *)(pointer - sizeof(cell));
|
return *(cell*)(pointer - sizeof(cell));
|
||||||
case RC_ABSOLUTE:
|
case RC_ABSOLUTE:
|
||||||
return *(u32 *)(pointer - sizeof(u32));
|
return *(u32*)(pointer - sizeof(u32));
|
||||||
case RC_RELATIVE:
|
case RC_RELATIVE:
|
||||||
return *(s32 *)(pointer - sizeof(u32)) + relative_to;
|
return *(s32*)(pointer - sizeof(u32)) + relative_to;
|
||||||
case RC_ABSOLUTE_PPC_2_2:
|
case RC_ABSOLUTE_PPC_2_2:
|
||||||
return load_value_2_2();
|
return load_value_2_2();
|
||||||
case RC_ABSOLUTE_PPC_2:
|
case RC_ABSOLUTE_PPC_2:
|
||||||
return load_value_masked(rel_absolute_ppc_2_mask,16,0);
|
return load_value_masked(rel_absolute_ppc_2_mask, 16, 0);
|
||||||
case RC_RELATIVE_PPC_2_PC:
|
case RC_RELATIVE_PPC_2_PC:
|
||||||
return load_value_masked(rel_relative_ppc_2_mask,16,0) + relative_to - 4;
|
return load_value_masked(rel_relative_ppc_2_mask, 16, 0) + relative_to -
|
||||||
|
4;
|
||||||
case RC_RELATIVE_PPC_3_PC:
|
case RC_RELATIVE_PPC_3_PC:
|
||||||
return load_value_masked(rel_relative_ppc_3_mask,6,0) + relative_to - 4;
|
return load_value_masked(rel_relative_ppc_3_mask, 6, 0) + relative_to - 4;
|
||||||
case RC_RELATIVE_ARM_3:
|
case RC_RELATIVE_ARM_3:
|
||||||
return load_value_masked(rel_relative_arm_3_mask,6,2) + relative_to + sizeof(cell);
|
return load_value_masked(rel_relative_arm_3_mask, 6, 2) + relative_to +
|
||||||
|
sizeof(cell);
|
||||||
case RC_INDIRECT_ARM:
|
case RC_INDIRECT_ARM:
|
||||||
return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to;
|
return load_value_masked(rel_indirect_arm_mask, 20, 0) + relative_to;
|
||||||
case RC_INDIRECT_ARM_PC:
|
case RC_INDIRECT_ARM_PC:
|
||||||
return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to + sizeof(cell);
|
return load_value_masked(rel_indirect_arm_mask, 20, 0) + relative_to +
|
||||||
|
sizeof(cell);
|
||||||
case RC_ABSOLUTE_2:
|
case RC_ABSOLUTE_2:
|
||||||
return *(u16 *)(pointer - sizeof(u16));
|
return *(u16*)(pointer - sizeof(u16));
|
||||||
case RC_ABSOLUTE_1:
|
case RC_ABSOLUTE_1:
|
||||||
return *(u8 *)(pointer - sizeof(u8));
|
return *(u8*)(pointer - sizeof(u8));
|
||||||
case RC_ABSOLUTE_PPC_2_2_2_2:
|
case RC_ABSOLUTE_PPC_2_2_2_2:
|
||||||
return load_value_2_2_2_2();
|
return load_value_2_2_2_2();
|
||||||
default:
|
default:
|
||||||
critical_error("Bad rel class",rel.rel_class());
|
critical_error("Bad rel class", rel.rel_class());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fixnum instruction_operand::load_value()
|
fixnum instruction_operand::load_value() { return load_value(pointer); }
|
||||||
{
|
|
||||||
return load_value(pointer);
|
code_block* instruction_operand::load_code_block(cell relative_to) {
|
||||||
|
return ((code_block*)load_value(relative_to) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
code_block *instruction_operand::load_code_block(cell relative_to)
|
code_block* instruction_operand::load_code_block() {
|
||||||
{
|
|
||||||
return ((code_block *)load_value(relative_to) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
code_block *instruction_operand::load_code_block()
|
|
||||||
{
|
|
||||||
return load_code_block(pointer);
|
return load_code_block(pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store a 32-bit value into a PowerPC LIS/ORI sequence */
|
/* Store a 32-bit value into a PowerPC LIS/ORI sequence */
|
||||||
void instruction_operand::store_value_2_2(fixnum value)
|
void instruction_operand::store_value_2_2(fixnum value) {
|
||||||
{
|
u32* ptr = (u32*)pointer;
|
||||||
u32 *ptr = (u32 *)pointer;
|
|
||||||
ptr[-2] = ((ptr[-2] & ~0xffff) | ((value >> 16) & 0xffff));
|
ptr[-2] = ((ptr[-2] & ~0xffff) | ((value >> 16) & 0xffff));
|
||||||
ptr[-1] = ((ptr[-1] & ~0xffff) | (value & 0xffff));
|
ptr[-1] = ((ptr[-1] & ~0xffff) | (value & 0xffff));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store a 64-bit value into a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence */
|
/* Store a 64-bit value into a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence */
|
||||||
void instruction_operand::store_value_2_2_2_2(fixnum value)
|
void instruction_operand::store_value_2_2_2_2(fixnum value) {
|
||||||
{
|
|
||||||
u64 val = value;
|
u64 val = value;
|
||||||
u32 *ptr = (u32 *)pointer;
|
u32* ptr = (u32*)pointer;
|
||||||
ptr[-5] = ((ptr[-5] & ~0xffff) | ((val >> 48) & 0xffff));
|
ptr[-5] = ((ptr[-5] & ~0xffff) | ((val >> 48) & 0xffff));
|
||||||
ptr[-4] = ((ptr[-4] & ~0xffff) | ((val >> 32) & 0xffff));
|
ptr[-4] = ((ptr[-4] & ~0xffff) | ((val >> 32) & 0xffff));
|
||||||
ptr[-2] = ((ptr[-2] & ~0xffff) | ((val >> 16) & 0xffff));
|
ptr[-2] = ((ptr[-2] & ~0xffff) | ((val >> 16) & 0xffff));
|
||||||
|
@ -106,66 +101,65 @@ void instruction_operand::store_value_2_2_2_2(fixnum value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store a value into a bitfield of a PowerPC instruction */
|
/* Store a value into a bitfield of a PowerPC instruction */
|
||||||
void instruction_operand::store_value_masked(fixnum value, cell mask, cell shift)
|
void instruction_operand::store_value_masked(fixnum value, cell mask,
|
||||||
{
|
cell shift) {
|
||||||
u32 *ptr = (u32 *)(pointer - sizeof(u32));
|
u32* ptr = (u32*)(pointer - sizeof(u32));
|
||||||
*ptr = (u32)((*ptr & ~mask) | ((value >> shift) & mask));
|
*ptr = (u32)((*ptr & ~mask) | ((value >> shift) & mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
void instruction_operand::store_value(fixnum absolute_value)
|
void instruction_operand::store_value(fixnum absolute_value) {
|
||||||
{
|
|
||||||
fixnum relative_value = absolute_value - pointer;
|
fixnum relative_value = absolute_value - pointer;
|
||||||
|
|
||||||
switch(rel.rel_class())
|
switch (rel.rel_class()) {
|
||||||
{
|
|
||||||
case RC_ABSOLUTE_CELL:
|
case RC_ABSOLUTE_CELL:
|
||||||
*(cell *)(pointer - sizeof(cell)) = absolute_value;
|
*(cell*)(pointer - sizeof(cell)) = absolute_value;
|
||||||
break;
|
break;
|
||||||
case RC_ABSOLUTE:
|
case RC_ABSOLUTE:
|
||||||
*(u32 *)(pointer - sizeof(u32)) = (u32)absolute_value;
|
*(u32*)(pointer - sizeof(u32)) = (u32) absolute_value;
|
||||||
break;
|
break;
|
||||||
case RC_RELATIVE:
|
case RC_RELATIVE:
|
||||||
*(s32 *)(pointer - sizeof(s32)) = (s32)relative_value;
|
*(s32*)(pointer - sizeof(s32)) = (s32) relative_value;
|
||||||
break;
|
break;
|
||||||
case RC_ABSOLUTE_PPC_2_2:
|
case RC_ABSOLUTE_PPC_2_2:
|
||||||
store_value_2_2(absolute_value);
|
store_value_2_2(absolute_value);
|
||||||
break;
|
break;
|
||||||
case RC_ABSOLUTE_PPC_2:
|
case RC_ABSOLUTE_PPC_2:
|
||||||
store_value_masked(absolute_value,rel_absolute_ppc_2_mask,0);
|
store_value_masked(absolute_value, rel_absolute_ppc_2_mask, 0);
|
||||||
break;
|
break;
|
||||||
case RC_RELATIVE_PPC_2_PC:
|
case RC_RELATIVE_PPC_2_PC:
|
||||||
store_value_masked(relative_value + 4,rel_relative_ppc_2_mask,0);
|
store_value_masked(relative_value + 4, rel_relative_ppc_2_mask, 0);
|
||||||
break;
|
break;
|
||||||
case RC_RELATIVE_PPC_3_PC:
|
case RC_RELATIVE_PPC_3_PC:
|
||||||
store_value_masked(relative_value + 4,rel_relative_ppc_3_mask,0);
|
store_value_masked(relative_value + 4, rel_relative_ppc_3_mask, 0);
|
||||||
break;
|
break;
|
||||||
case RC_RELATIVE_ARM_3:
|
case RC_RELATIVE_ARM_3:
|
||||||
store_value_masked(relative_value - sizeof(cell),rel_relative_arm_3_mask,2);
|
store_value_masked(relative_value - sizeof(cell), rel_relative_arm_3_mask,
|
||||||
|
2);
|
||||||
break;
|
break;
|
||||||
case RC_INDIRECT_ARM:
|
case RC_INDIRECT_ARM:
|
||||||
store_value_masked(relative_value,rel_indirect_arm_mask,0);
|
store_value_masked(relative_value, rel_indirect_arm_mask, 0);
|
||||||
break;
|
break;
|
||||||
case RC_INDIRECT_ARM_PC:
|
case RC_INDIRECT_ARM_PC:
|
||||||
store_value_masked(relative_value - sizeof(cell),rel_indirect_arm_mask,0);
|
store_value_masked(relative_value - sizeof(cell), rel_indirect_arm_mask,
|
||||||
|
0);
|
||||||
break;
|
break;
|
||||||
case RC_ABSOLUTE_2:
|
case RC_ABSOLUTE_2:
|
||||||
*(u16 *)(pointer - sizeof(u16)) = (u16)absolute_value;
|
*(u16*)(pointer - sizeof(u16)) = (u16) absolute_value;
|
||||||
break;
|
break;
|
||||||
case RC_ABSOLUTE_1:
|
case RC_ABSOLUTE_1:
|
||||||
*(u8 *)(pointer - sizeof(u8)) = (u8)absolute_value;
|
*(u8*)(pointer - sizeof(u8)) = (u8) absolute_value;
|
||||||
break;
|
break;
|
||||||
case RC_ABSOLUTE_PPC_2_2_2_2:
|
case RC_ABSOLUTE_PPC_2_2_2_2:
|
||||||
store_value_2_2_2_2(absolute_value);
|
store_value_2_2_2_2(absolute_value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
critical_error("Bad rel class",rel.rel_class());
|
critical_error("Bad rel class", rel.rel_class());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void instruction_operand::store_code_block(code_block *compiled)
|
void instruction_operand::store_code_block(code_block* compiled) {
|
||||||
{
|
store_value((cell) compiled->entry_point());
|
||||||
store_value((cell)compiled->entry_point());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
namespace factor
|
namespace factor {
|
||||||
{
|
|
||||||
|
|
||||||
enum relocation_type {
|
enum relocation_type {
|
||||||
/* arg is a literal table index, holding a pair (symbol/dll) */
|
/* arg is a literal table index, holding a pair (symbol/dll) */
|
||||||
|
@ -80,32 +79,23 @@ struct relocation_entry {
|
||||||
|
|
||||||
explicit relocation_entry(u32 value_) : value(value_) {}
|
explicit relocation_entry(u32 value_) : value(value_) {}
|
||||||
|
|
||||||
relocation_entry(relocation_type rel_type,
|
relocation_entry(relocation_type rel_type, relocation_class rel_class,
|
||||||
relocation_class rel_class,
|
cell offset) {
|
||||||
cell offset)
|
|
||||||
{
|
|
||||||
value = (u32)((rel_type << 28) | (rel_class << 24) | offset);
|
value = (u32)((rel_type << 28) | (rel_class << 24) | offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
relocation_type rel_type()
|
relocation_type rel_type() {
|
||||||
{
|
|
||||||
return (relocation_type)((value & 0xf0000000) >> 28);
|
return (relocation_type)((value & 0xf0000000) >> 28);
|
||||||
}
|
}
|
||||||
|
|
||||||
relocation_class rel_class()
|
relocation_class rel_class() {
|
||||||
{
|
|
||||||
return (relocation_class)((value & 0x0f000000) >> 24);
|
return (relocation_class)((value & 0x0f000000) >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
cell rel_offset()
|
cell rel_offset() { return (value & 0x00ffffff); }
|
||||||
{
|
|
||||||
return (value & 0x00ffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
int number_of_parameters()
|
int number_of_parameters() {
|
||||||
{
|
switch (rel_type()) {
|
||||||
switch(rel_type())
|
|
||||||
{
|
|
||||||
case RT_VM:
|
case RT_VM:
|
||||||
return 1;
|
return 1;
|
||||||
case RT_DLSYM:
|
case RT_DLSYM:
|
||||||
|
@ -126,7 +116,7 @@ struct relocation_entry {
|
||||||
case RT_SAFEPOINT:
|
case RT_SAFEPOINT:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
critical_error("Bad rel type in number_of_parameters()",rel_type());
|
critical_error("Bad rel type in number_of_parameters()", rel_type());
|
||||||
return -1; /* Can't happen */
|
return -1; /* Can't happen */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,35 +124,30 @@ struct relocation_entry {
|
||||||
|
|
||||||
struct instruction_operand {
|
struct instruction_operand {
|
||||||
relocation_entry rel;
|
relocation_entry rel;
|
||||||
code_block *compiled;
|
code_block* compiled;
|
||||||
cell index;
|
cell index;
|
||||||
cell pointer;
|
cell pointer;
|
||||||
|
|
||||||
instruction_operand(relocation_entry rel_, code_block *compiled_, cell index_);
|
instruction_operand(relocation_entry rel_, code_block* compiled_,
|
||||||
|
cell index_);
|
||||||
|
|
||||||
relocation_type rel_type()
|
relocation_type rel_type() { return rel.rel_type(); }
|
||||||
{
|
|
||||||
return rel.rel_type();
|
|
||||||
}
|
|
||||||
|
|
||||||
cell rel_offset()
|
cell rel_offset() { return rel.rel_offset(); }
|
||||||
{
|
|
||||||
return rel.rel_offset();
|
|
||||||
}
|
|
||||||
|
|
||||||
fixnum load_value_2_2();
|
fixnum load_value_2_2();
|
||||||
fixnum load_value_2_2_2_2();
|
fixnum load_value_2_2_2_2();
|
||||||
fixnum load_value_masked(cell mask, cell bits, cell shift);
|
fixnum load_value_masked(cell mask, cell bits, cell shift);
|
||||||
fixnum load_value(cell relative_to);
|
fixnum load_value(cell relative_to);
|
||||||
fixnum load_value();
|
fixnum load_value();
|
||||||
code_block *load_code_block(cell relative_to);
|
code_block* load_code_block(cell relative_to);
|
||||||
code_block *load_code_block();
|
code_block* load_code_block();
|
||||||
|
|
||||||
void store_value_2_2(fixnum value);
|
void store_value_2_2(fixnum value);
|
||||||
void store_value_2_2_2_2(fixnum value);
|
void store_value_2_2_2_2(fixnum value);
|
||||||
void store_value_masked(fixnum value, cell mask, cell shift);
|
void store_value_masked(fixnum value, cell mask, cell shift);
|
||||||
void store_value(fixnum value);
|
void store_value(fixnum value);
|
||||||
void store_code_block(code_block *compiled);
|
void store_code_block(code_block* compiled);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue