VM: Refactor instruction_operands.cpp/hpp to Factor style

db4
Erik Charlebois 2013-05-11 22:06:39 -04:00
parent f6047832cb
commit d3d1d3bb7a
2 changed files with 251 additions and 272 deletions

View File

@ -1,14 +1,16 @@
#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);
@ -16,8 +18,7 @@ fixnum instruction_operand::load_value_2_2()
} }
/* 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);
@ -28,17 +29,15 @@ fixnum instruction_operand::load_value_2_2_2_2()
} }
/* 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:
@ -50,15 +49,18 @@ fixnum instruction_operand::load_value(cell relative_to)
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:
@ -71,32 +73,25 @@ fixnum instruction_operand::load_value(cell relative_to)
} }
} }
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) code_block* instruction_operand::load_code_block(cell relative_to) {
{
return ((code_block*)load_value(relative_to) - 1); return ((code_block*)load_value(relative_to) - 1);
} }
code_block *instruction_operand::load_code_block() 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));
@ -106,18 +101,16 @@ 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;
@ -140,13 +133,15 @@ void instruction_operand::store_value(fixnum absolute_value)
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;
@ -163,8 +158,7 @@ void instruction_operand::store_value(fixnum absolute_value)
} }
} }
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());
} }

View File

@ -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:
@ -138,17 +128,12 @@ struct instruction_operand {
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();