VM: Refactor instruction_operands.cpp/hpp to Factor style
							parent
							
								
									f6047832cb
								
							
						
					
					
						commit
						d3d1d3bb7a
					
				| 
						 | 
				
			
			@ -1,171 +1,165 @@
 | 
			
		|||
#include "master.hpp"
 | 
			
		||||
 | 
			
		||||
namespace factor
 | 
			
		||||
{
 | 
			
		||||
namespace factor {
 | 
			
		||||
 | 
			
		||||
instruction_operand::instruction_operand(relocation_entry rel_, code_block *compiled_, cell index_) :
 | 
			
		||||
	rel(rel_), compiled(compiled_), index(index_), pointer((cell)compiled_->entry_point() + rel_.rel_offset()) {}
 | 
			
		||||
instruction_operand::instruction_operand(relocation_entry rel_,
 | 
			
		||||
                                         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 */
 | 
			
		||||
fixnum instruction_operand::load_value_2_2()
 | 
			
		||||
{
 | 
			
		||||
	u32 *ptr = (u32 *)pointer;
 | 
			
		||||
	cell hi = (ptr[-2] & 0xffff);
 | 
			
		||||
	cell lo = (ptr[-1] & 0xffff);
 | 
			
		||||
	return hi << 16 | lo;
 | 
			
		||||
fixnum instruction_operand::load_value_2_2() {
 | 
			
		||||
  u32* ptr = (u32*)pointer;
 | 
			
		||||
  cell hi = (ptr[-2] & 0xffff);
 | 
			
		||||
  cell lo = (ptr[-1] & 0xffff);
 | 
			
		||||
  return hi << 16 | lo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Load a 64-bit value from a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence */
 | 
			
		||||
fixnum instruction_operand::load_value_2_2_2_2()
 | 
			
		||||
{
 | 
			
		||||
	u32 *ptr = (u32 *)pointer;
 | 
			
		||||
	u64 hhi = (ptr[-5] & 0xffff);
 | 
			
		||||
	u64 hlo = (ptr[-4] & 0xffff);
 | 
			
		||||
	u64 lhi = (ptr[-2] & 0xffff);
 | 
			
		||||
	u64 llo = (ptr[-1] & 0xffff);
 | 
			
		||||
	u64 val = hhi << 48 | hlo << 32 | lhi << 16 | llo;
 | 
			
		||||
	return (cell)val;
 | 
			
		||||
fixnum instruction_operand::load_value_2_2_2_2() {
 | 
			
		||||
  u32* ptr = (u32*)pointer;
 | 
			
		||||
  u64 hhi = (ptr[-5] & 0xffff);
 | 
			
		||||
  u64 hlo = (ptr[-4] & 0xffff);
 | 
			
		||||
  u64 lhi = (ptr[-2] & 0xffff);
 | 
			
		||||
  u64 llo = (ptr[-1] & 0xffff);
 | 
			
		||||
  u64 val = hhi << 48 | hlo << 32 | lhi << 16 | llo;
 | 
			
		||||
  return (cell) val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Load a value from a bitfield of a PowerPC instruction */
 | 
			
		||||
fixnum instruction_operand::load_value_masked(cell mask, cell bits, cell shift)
 | 
			
		||||
{
 | 
			
		||||
	s32 *ptr = (s32 *)(pointer - sizeof(u32));
 | 
			
		||||
fixnum instruction_operand::load_value_masked(cell mask, cell bits,
 | 
			
		||||
                                              cell shift) {
 | 
			
		||||
  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)
 | 
			
		||||
{
 | 
			
		||||
	switch(rel.rel_class())
 | 
			
		||||
	{
 | 
			
		||||
	case RC_ABSOLUTE_CELL:
 | 
			
		||||
		return *(cell *)(pointer - sizeof(cell));
 | 
			
		||||
	case RC_ABSOLUTE:
 | 
			
		||||
		return *(u32 *)(pointer - sizeof(u32));
 | 
			
		||||
	case RC_RELATIVE:
 | 
			
		||||
		return *(s32 *)(pointer - sizeof(u32)) + relative_to;
 | 
			
		||||
	case RC_ABSOLUTE_PPC_2_2:
 | 
			
		||||
		return load_value_2_2();
 | 
			
		||||
	case RC_ABSOLUTE_PPC_2:
 | 
			
		||||
		return load_value_masked(rel_absolute_ppc_2_mask,16,0);
 | 
			
		||||
	case RC_RELATIVE_PPC_2_PC:
 | 
			
		||||
		return load_value_masked(rel_relative_ppc_2_mask,16,0) + relative_to - 4;
 | 
			
		||||
	case RC_RELATIVE_PPC_3_PC:
 | 
			
		||||
		return load_value_masked(rel_relative_ppc_3_mask,6,0) + relative_to - 4;
 | 
			
		||||
	case RC_RELATIVE_ARM_3:
 | 
			
		||||
		return load_value_masked(rel_relative_arm_3_mask,6,2) + relative_to + sizeof(cell);
 | 
			
		||||
	case RC_INDIRECT_ARM:
 | 
			
		||||
		return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to;
 | 
			
		||||
	case RC_INDIRECT_ARM_PC:
 | 
			
		||||
		return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to + sizeof(cell);
 | 
			
		||||
	case RC_ABSOLUTE_2:
 | 
			
		||||
		return *(u16 *)(pointer - sizeof(u16));
 | 
			
		||||
	case RC_ABSOLUTE_1:
 | 
			
		||||
		return *(u8 *)(pointer - sizeof(u8));
 | 
			
		||||
	case RC_ABSOLUTE_PPC_2_2_2_2:
 | 
			
		||||
		return load_value_2_2_2_2();
 | 
			
		||||
	default:
 | 
			
		||||
		critical_error("Bad rel class",rel.rel_class());
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
fixnum instruction_operand::load_value(cell relative_to) {
 | 
			
		||||
  switch (rel.rel_class()) {
 | 
			
		||||
    case RC_ABSOLUTE_CELL:
 | 
			
		||||
      return *(cell*)(pointer - sizeof(cell));
 | 
			
		||||
    case RC_ABSOLUTE:
 | 
			
		||||
      return *(u32*)(pointer - sizeof(u32));
 | 
			
		||||
    case RC_RELATIVE:
 | 
			
		||||
      return *(s32*)(pointer - sizeof(u32)) + relative_to;
 | 
			
		||||
    case RC_ABSOLUTE_PPC_2_2:
 | 
			
		||||
      return load_value_2_2();
 | 
			
		||||
    case RC_ABSOLUTE_PPC_2:
 | 
			
		||||
      return load_value_masked(rel_absolute_ppc_2_mask, 16, 0);
 | 
			
		||||
    case RC_RELATIVE_PPC_2_PC:
 | 
			
		||||
      return load_value_masked(rel_relative_ppc_2_mask, 16, 0) + relative_to -
 | 
			
		||||
             4;
 | 
			
		||||
    case RC_RELATIVE_PPC_3_PC:
 | 
			
		||||
      return load_value_masked(rel_relative_ppc_3_mask, 6, 0) + relative_to - 4;
 | 
			
		||||
    case RC_RELATIVE_ARM_3:
 | 
			
		||||
      return load_value_masked(rel_relative_arm_3_mask, 6, 2) + relative_to +
 | 
			
		||||
             sizeof(cell);
 | 
			
		||||
    case RC_INDIRECT_ARM:
 | 
			
		||||
      return load_value_masked(rel_indirect_arm_mask, 20, 0) + relative_to;
 | 
			
		||||
    case RC_INDIRECT_ARM_PC:
 | 
			
		||||
      return load_value_masked(rel_indirect_arm_mask, 20, 0) + relative_to +
 | 
			
		||||
             sizeof(cell);
 | 
			
		||||
    case RC_ABSOLUTE_2:
 | 
			
		||||
      return *(u16*)(pointer - sizeof(u16));
 | 
			
		||||
    case RC_ABSOLUTE_1:
 | 
			
		||||
      return *(u8*)(pointer - sizeof(u8));
 | 
			
		||||
    case RC_ABSOLUTE_PPC_2_2_2_2:
 | 
			
		||||
      return load_value_2_2_2_2();
 | 
			
		||||
    default:
 | 
			
		||||
      critical_error("Bad rel class", rel.rel_class());
 | 
			
		||||
      return 0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fixnum instruction_operand::load_value()
 | 
			
		||||
{
 | 
			
		||||
	return load_value(pointer);
 | 
			
		||||
fixnum instruction_operand::load_value() { 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)
 | 
			
		||||
{
 | 
			
		||||
	return ((code_block *)load_value(relative_to) - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
code_block *instruction_operand::load_code_block()
 | 
			
		||||
{
 | 
			
		||||
	return load_code_block(pointer);
 | 
			
		||||
code_block* instruction_operand::load_code_block() {
 | 
			
		||||
  return load_code_block(pointer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Store a 32-bit value into a PowerPC LIS/ORI sequence */
 | 
			
		||||
void instruction_operand::store_value_2_2(fixnum value)
 | 
			
		||||
{
 | 
			
		||||
	u32 *ptr = (u32 *)pointer;
 | 
			
		||||
	ptr[-2] = ((ptr[-2] & ~0xffff) | ((value >> 16) & 0xffff));
 | 
			
		||||
	ptr[-1] = ((ptr[-1] & ~0xffff) | (value & 0xffff));
 | 
			
		||||
void instruction_operand::store_value_2_2(fixnum value) {
 | 
			
		||||
  u32* ptr = (u32*)pointer;
 | 
			
		||||
  ptr[-2] = ((ptr[-2] & ~0xffff) | ((value >> 16) & 0xffff));
 | 
			
		||||
  ptr[-1] = ((ptr[-1] & ~0xffff) | (value & 0xffff));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 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)
 | 
			
		||||
{
 | 
			
		||||
	u64 val = value;
 | 
			
		||||
	u32 *ptr = (u32 *)pointer;
 | 
			
		||||
	ptr[-5] = ((ptr[-5] & ~0xffff) | ((val >> 48) & 0xffff));
 | 
			
		||||
	ptr[-4] = ((ptr[-4] & ~0xffff) | ((val >> 32) & 0xffff));
 | 
			
		||||
	ptr[-2] = ((ptr[-2] & ~0xffff) | ((val >> 16) & 0xffff));
 | 
			
		||||
	ptr[-1] = ((ptr[-1] & ~0xffff) | ((val >>  0) & 0xffff));
 | 
			
		||||
void instruction_operand::store_value_2_2_2_2(fixnum value) {
 | 
			
		||||
  u64 val = value;
 | 
			
		||||
  u32* ptr = (u32*)pointer;
 | 
			
		||||
  ptr[-5] = ((ptr[-5] & ~0xffff) | ((val >> 48) & 0xffff));
 | 
			
		||||
  ptr[-4] = ((ptr[-4] & ~0xffff) | ((val >> 32) & 0xffff));
 | 
			
		||||
  ptr[-2] = ((ptr[-2] & ~0xffff) | ((val >> 16) & 0xffff));
 | 
			
		||||
  ptr[-1] = ((ptr[-1] & ~0xffff) | ((val >> 0) & 0xffff));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Store a value into a bitfield of a PowerPC instruction */
 | 
			
		||||
void instruction_operand::store_value_masked(fixnum value, cell mask, cell shift)
 | 
			
		||||
{
 | 
			
		||||
	u32 *ptr = (u32 *)(pointer - sizeof(u32));
 | 
			
		||||
	*ptr = (u32)((*ptr & ~mask) | ((value >> shift) & mask));
 | 
			
		||||
void instruction_operand::store_value_masked(fixnum value, cell mask,
 | 
			
		||||
                                             cell shift) {
 | 
			
		||||
  u32* ptr = (u32*)(pointer - sizeof(u32));
 | 
			
		||||
  *ptr = (u32)((*ptr & ~mask) | ((value >> shift) & mask));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void instruction_operand::store_value(fixnum absolute_value)
 | 
			
		||||
{
 | 
			
		||||
	fixnum relative_value = absolute_value - pointer;
 | 
			
		||||
void instruction_operand::store_value(fixnum absolute_value) {
 | 
			
		||||
  fixnum relative_value = absolute_value - pointer;
 | 
			
		||||
 | 
			
		||||
	switch(rel.rel_class())
 | 
			
		||||
	{
 | 
			
		||||
	case RC_ABSOLUTE_CELL:
 | 
			
		||||
		*(cell *)(pointer - sizeof(cell)) = absolute_value;
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_ABSOLUTE:
 | 
			
		||||
		*(u32 *)(pointer - sizeof(u32)) = (u32)absolute_value;
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_RELATIVE:
 | 
			
		||||
		*(s32 *)(pointer - sizeof(s32)) = (s32)relative_value;
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_ABSOLUTE_PPC_2_2:
 | 
			
		||||
		store_value_2_2(absolute_value);
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_ABSOLUTE_PPC_2:
 | 
			
		||||
		store_value_masked(absolute_value,rel_absolute_ppc_2_mask,0);
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_RELATIVE_PPC_2_PC:
 | 
			
		||||
		store_value_masked(relative_value + 4,rel_relative_ppc_2_mask,0);
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_RELATIVE_PPC_3_PC:
 | 
			
		||||
		store_value_masked(relative_value + 4,rel_relative_ppc_3_mask,0);
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_RELATIVE_ARM_3:
 | 
			
		||||
		store_value_masked(relative_value - sizeof(cell),rel_relative_arm_3_mask,2);
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_INDIRECT_ARM:
 | 
			
		||||
		store_value_masked(relative_value,rel_indirect_arm_mask,0);
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_INDIRECT_ARM_PC:
 | 
			
		||||
		store_value_masked(relative_value - sizeof(cell),rel_indirect_arm_mask,0);
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_ABSOLUTE_2:
 | 
			
		||||
		*(u16 *)(pointer - sizeof(u16)) = (u16)absolute_value;
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_ABSOLUTE_1:
 | 
			
		||||
		*(u8 *)(pointer - sizeof(u8)) = (u8)absolute_value;
 | 
			
		||||
		break;
 | 
			
		||||
	case RC_ABSOLUTE_PPC_2_2_2_2:
 | 
			
		||||
		store_value_2_2_2_2(absolute_value);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		critical_error("Bad rel class",rel.rel_class());
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
  switch (rel.rel_class()) {
 | 
			
		||||
    case RC_ABSOLUTE_CELL:
 | 
			
		||||
      *(cell*)(pointer - sizeof(cell)) = absolute_value;
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_ABSOLUTE:
 | 
			
		||||
      *(u32*)(pointer - sizeof(u32)) = (u32) absolute_value;
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_RELATIVE:
 | 
			
		||||
      *(s32*)(pointer - sizeof(s32)) = (s32) relative_value;
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_ABSOLUTE_PPC_2_2:
 | 
			
		||||
      store_value_2_2(absolute_value);
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_ABSOLUTE_PPC_2:
 | 
			
		||||
      store_value_masked(absolute_value, rel_absolute_ppc_2_mask, 0);
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_RELATIVE_PPC_2_PC:
 | 
			
		||||
      store_value_masked(relative_value + 4, rel_relative_ppc_2_mask, 0);
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_RELATIVE_PPC_3_PC:
 | 
			
		||||
      store_value_masked(relative_value + 4, rel_relative_ppc_3_mask, 0);
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_RELATIVE_ARM_3:
 | 
			
		||||
      store_value_masked(relative_value - sizeof(cell), rel_relative_arm_3_mask,
 | 
			
		||||
                         2);
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_INDIRECT_ARM:
 | 
			
		||||
      store_value_masked(relative_value, rel_indirect_arm_mask, 0);
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_INDIRECT_ARM_PC:
 | 
			
		||||
      store_value_masked(relative_value - sizeof(cell), rel_indirect_arm_mask,
 | 
			
		||||
                         0);
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_ABSOLUTE_2:
 | 
			
		||||
      *(u16*)(pointer - sizeof(u16)) = (u16) absolute_value;
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_ABSOLUTE_1:
 | 
			
		||||
      *(u8*)(pointer - sizeof(u8)) = (u8) absolute_value;
 | 
			
		||||
      break;
 | 
			
		||||
    case RC_ABSOLUTE_PPC_2_2_2_2:
 | 
			
		||||
      store_value_2_2_2_2(absolute_value);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      critical_error("Bad rel class", rel.rel_class());
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void instruction_operand::store_code_block(code_block *compiled)
 | 
			
		||||
{
 | 
			
		||||
	store_value((cell)compiled->entry_point());
 | 
			
		||||
void instruction_operand::store_code_block(code_block* compiled) {
 | 
			
		||||
  store_value((cell) compiled->entry_point());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,168 +1,153 @@
 | 
			
		|||
namespace factor
 | 
			
		||||
{
 | 
			
		||||
namespace factor {
 | 
			
		||||
 | 
			
		||||
enum relocation_type {
 | 
			
		||||
	/* arg is a literal table index, holding a pair (symbol/dll) */
 | 
			
		||||
	RT_DLSYM,
 | 
			
		||||
	/* a word or quotation's general entry point */
 | 
			
		||||
	RT_ENTRY_POINT,
 | 
			
		||||
	/* a word's PIC entry point */
 | 
			
		||||
	RT_ENTRY_POINT_PIC,
 | 
			
		||||
	/* a word's tail-call PIC entry point */
 | 
			
		||||
	RT_ENTRY_POINT_PIC_TAIL,
 | 
			
		||||
	/* current offset */
 | 
			
		||||
	RT_HERE,
 | 
			
		||||
	/* current code block */
 | 
			
		||||
	RT_THIS,
 | 
			
		||||
	/* data heap literal */
 | 
			
		||||
	RT_LITERAL,
 | 
			
		||||
	/* untagged fixnum literal */
 | 
			
		||||
	RT_UNTAGGED,
 | 
			
		||||
	/* address of megamorphic_cache_hits var */
 | 
			
		||||
	RT_MEGAMORPHIC_CACHE_HITS,
 | 
			
		||||
	/* address of vm object */
 | 
			
		||||
	RT_VM,
 | 
			
		||||
	/* value of vm->cards_offset */
 | 
			
		||||
	RT_CARDS_OFFSET,
 | 
			
		||||
	/* value of vm->decks_offset */
 | 
			
		||||
	RT_DECKS_OFFSET,
 | 
			
		||||
	/* address of exception_handler -- this exists as a separate relocation
 | 
			
		||||
	type since its used in a situation where relocation arguments cannot
 | 
			
		||||
	be passed in, and so RT_DLSYM is inappropriate (Windows only) */
 | 
			
		||||
	RT_EXCEPTION_HANDLER,
 | 
			
		||||
	/* arg is a literal table index, holding a pair (symbol/dll) */
 | 
			
		||||
	RT_DLSYM_TOC,
 | 
			
		||||
	/* address of inline_cache_miss function. This is a separate
 | 
			
		||||
  /* arg is a literal table index, holding a pair (symbol/dll) */
 | 
			
		||||
  RT_DLSYM,
 | 
			
		||||
  /* a word or quotation's general entry point */
 | 
			
		||||
  RT_ENTRY_POINT,
 | 
			
		||||
  /* a word's PIC entry point */
 | 
			
		||||
  RT_ENTRY_POINT_PIC,
 | 
			
		||||
  /* a word's tail-call PIC entry point */
 | 
			
		||||
  RT_ENTRY_POINT_PIC_TAIL,
 | 
			
		||||
  /* current offset */
 | 
			
		||||
  RT_HERE,
 | 
			
		||||
  /* current code block */
 | 
			
		||||
  RT_THIS,
 | 
			
		||||
  /* data heap literal */
 | 
			
		||||
  RT_LITERAL,
 | 
			
		||||
  /* untagged fixnum literal */
 | 
			
		||||
  RT_UNTAGGED,
 | 
			
		||||
  /* address of megamorphic_cache_hits var */
 | 
			
		||||
  RT_MEGAMORPHIC_CACHE_HITS,
 | 
			
		||||
  /* address of vm object */
 | 
			
		||||
  RT_VM,
 | 
			
		||||
  /* value of vm->cards_offset */
 | 
			
		||||
  RT_CARDS_OFFSET,
 | 
			
		||||
  /* value of vm->decks_offset */
 | 
			
		||||
  RT_DECKS_OFFSET,
 | 
			
		||||
  /* address of exception_handler -- this exists as a separate relocation
 | 
			
		||||
     type since its used in a situation where relocation arguments cannot
 | 
			
		||||
     be passed in, and so RT_DLSYM is inappropriate (Windows only) */
 | 
			
		||||
  RT_EXCEPTION_HANDLER,
 | 
			
		||||
  /* arg is a literal table index, holding a pair (symbol/dll) */
 | 
			
		||||
  RT_DLSYM_TOC,
 | 
			
		||||
  /* address of inline_cache_miss function. This is a separate
 | 
			
		||||
	relocation to reduce compile time and size for PICs. */
 | 
			
		||||
	RT_INLINE_CACHE_MISS,
 | 
			
		||||
	/* address of safepoint page in code heap */
 | 
			
		||||
	RT_SAFEPOINT
 | 
			
		||||
  RT_INLINE_CACHE_MISS,
 | 
			
		||||
  /* address of safepoint page in code heap */
 | 
			
		||||
  RT_SAFEPOINT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum relocation_class {
 | 
			
		||||
	/* absolute address in a pointer-width location */
 | 
			
		||||
	RC_ABSOLUTE_CELL,
 | 
			
		||||
	/* absolute address in a 4 byte location */
 | 
			
		||||
	RC_ABSOLUTE,
 | 
			
		||||
	/* relative address in a 4 byte location */
 | 
			
		||||
	RC_RELATIVE,
 | 
			
		||||
	/* absolute address in a PowerPC LIS/ORI sequence */
 | 
			
		||||
	RC_ABSOLUTE_PPC_2_2,
 | 
			
		||||
	/* absolute address in a PowerPC LWZ instruction */
 | 
			
		||||
	RC_ABSOLUTE_PPC_2,
 | 
			
		||||
	/* relative address in a PowerPC LWZ/STW/BC instruction */
 | 
			
		||||
	RC_RELATIVE_PPC_2_PC,
 | 
			
		||||
	/* relative address in a PowerPC B/BL instruction */
 | 
			
		||||
	RC_RELATIVE_PPC_3_PC,
 | 
			
		||||
	/* relative address in an ARM B/BL instruction */
 | 
			
		||||
	RC_RELATIVE_ARM_3,
 | 
			
		||||
	/* pointer to address in an ARM LDR/STR instruction */
 | 
			
		||||
	RC_INDIRECT_ARM,
 | 
			
		||||
	/* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */
 | 
			
		||||
	RC_INDIRECT_ARM_PC,
 | 
			
		||||
	/* absolute address in a 2 byte location */
 | 
			
		||||
	RC_ABSOLUTE_2,
 | 
			
		||||
	/* absolute address in a 1 byte location */
 | 
			
		||||
	RC_ABSOLUTE_1,
 | 
			
		||||
	/* absolute address in a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence */
 | 
			
		||||
	RC_ABSOLUTE_PPC_2_2_2_2,
 | 
			
		||||
  /* absolute address in a pointer-width location */
 | 
			
		||||
  RC_ABSOLUTE_CELL,
 | 
			
		||||
  /* absolute address in a 4 byte location */
 | 
			
		||||
  RC_ABSOLUTE,
 | 
			
		||||
  /* relative address in a 4 byte location */
 | 
			
		||||
  RC_RELATIVE,
 | 
			
		||||
  /* absolute address in a PowerPC LIS/ORI sequence */
 | 
			
		||||
  RC_ABSOLUTE_PPC_2_2,
 | 
			
		||||
  /* absolute address in a PowerPC LWZ instruction */
 | 
			
		||||
  RC_ABSOLUTE_PPC_2,
 | 
			
		||||
  /* relative address in a PowerPC LWZ/STW/BC instruction */
 | 
			
		||||
  RC_RELATIVE_PPC_2_PC,
 | 
			
		||||
  /* relative address in a PowerPC B/BL instruction */
 | 
			
		||||
  RC_RELATIVE_PPC_3_PC,
 | 
			
		||||
  /* relative address in an ARM B/BL instruction */
 | 
			
		||||
  RC_RELATIVE_ARM_3,
 | 
			
		||||
  /* pointer to address in an ARM LDR/STR instruction */
 | 
			
		||||
  RC_INDIRECT_ARM,
 | 
			
		||||
  /* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */
 | 
			
		||||
  RC_INDIRECT_ARM_PC,
 | 
			
		||||
  /* absolute address in a 2 byte location */
 | 
			
		||||
  RC_ABSOLUTE_2,
 | 
			
		||||
  /* absolute address in a 1 byte location */
 | 
			
		||||
  RC_ABSOLUTE_1,
 | 
			
		||||
  /* absolute address in a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence */
 | 
			
		||||
  RC_ABSOLUTE_PPC_2_2_2_2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const cell rel_absolute_ppc_2_mask = 0x0000ffff;
 | 
			
		||||
static const cell rel_relative_ppc_2_mask = 0x0000fffc;
 | 
			
		||||
static const cell rel_relative_ppc_3_mask = 0x03fffffc;
 | 
			
		||||
static const cell rel_indirect_arm_mask   = 0x00000fff;
 | 
			
		||||
static const cell rel_indirect_arm_mask = 0x00000fff;
 | 
			
		||||
static const cell rel_relative_arm_3_mask = 0x00ffffff;
 | 
			
		||||
 | 
			
		||||
/* code relocation table consists of a table of entries for each fixup */
 | 
			
		||||
struct relocation_entry {
 | 
			
		||||
	u32 value;
 | 
			
		||||
  u32 value;
 | 
			
		||||
 | 
			
		||||
	explicit relocation_entry(u32 value_) : value(value_) {}
 | 
			
		||||
  explicit relocation_entry(u32 value_) : value(value_) {}
 | 
			
		||||
 | 
			
		||||
	relocation_entry(relocation_type rel_type,
 | 
			
		||||
		relocation_class rel_class,
 | 
			
		||||
		cell offset)
 | 
			
		||||
	{
 | 
			
		||||
		value = (u32)((rel_type << 28) | (rel_class << 24) | offset);
 | 
			
		||||
	}
 | 
			
		||||
  relocation_entry(relocation_type rel_type, relocation_class rel_class,
 | 
			
		||||
                   cell offset) {
 | 
			
		||||
    value = (u32)((rel_type << 28) | (rel_class << 24) | offset);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
	relocation_type rel_type()
 | 
			
		||||
	{
 | 
			
		||||
		return (relocation_type)((value & 0xf0000000) >> 28);
 | 
			
		||||
	}
 | 
			
		||||
  relocation_type rel_type() {
 | 
			
		||||
    return (relocation_type)((value & 0xf0000000) >> 28);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
	relocation_class rel_class()
 | 
			
		||||
	{
 | 
			
		||||
		return (relocation_class)((value & 0x0f000000) >> 24);
 | 
			
		||||
	}
 | 
			
		||||
  relocation_class rel_class() {
 | 
			
		||||
    return (relocation_class)((value & 0x0f000000) >> 24);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
	cell rel_offset()
 | 
			
		||||
	{
 | 
			
		||||
		return (value & 0x00ffffff);
 | 
			
		||||
	}
 | 
			
		||||
  cell rel_offset() { return (value & 0x00ffffff); }
 | 
			
		||||
 | 
			
		||||
	int number_of_parameters()
 | 
			
		||||
	{
 | 
			
		||||
		switch(rel_type())
 | 
			
		||||
		{
 | 
			
		||||
		case RT_VM:
 | 
			
		||||
			return 1;
 | 
			
		||||
		case RT_DLSYM:
 | 
			
		||||
		case RT_DLSYM_TOC:
 | 
			
		||||
			return 2;
 | 
			
		||||
		case RT_ENTRY_POINT:
 | 
			
		||||
		case RT_ENTRY_POINT_PIC:
 | 
			
		||||
		case RT_ENTRY_POINT_PIC_TAIL:
 | 
			
		||||
		case RT_LITERAL:
 | 
			
		||||
		case RT_HERE:
 | 
			
		||||
		case RT_UNTAGGED:
 | 
			
		||||
		case RT_THIS:
 | 
			
		||||
		case RT_MEGAMORPHIC_CACHE_HITS:
 | 
			
		||||
		case RT_CARDS_OFFSET:
 | 
			
		||||
		case RT_DECKS_OFFSET:
 | 
			
		||||
		case RT_EXCEPTION_HANDLER:
 | 
			
		||||
		case RT_INLINE_CACHE_MISS:
 | 
			
		||||
		case RT_SAFEPOINT:
 | 
			
		||||
			return 0;
 | 
			
		||||
		default:
 | 
			
		||||
			critical_error("Bad rel type in number_of_parameters()",rel_type());
 | 
			
		||||
			return -1; /* Can't happen */
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
  int number_of_parameters() {
 | 
			
		||||
    switch (rel_type()) {
 | 
			
		||||
      case RT_VM:
 | 
			
		||||
        return 1;
 | 
			
		||||
      case RT_DLSYM:
 | 
			
		||||
      case RT_DLSYM_TOC:
 | 
			
		||||
        return 2;
 | 
			
		||||
      case RT_ENTRY_POINT:
 | 
			
		||||
      case RT_ENTRY_POINT_PIC:
 | 
			
		||||
      case RT_ENTRY_POINT_PIC_TAIL:
 | 
			
		||||
      case RT_LITERAL:
 | 
			
		||||
      case RT_HERE:
 | 
			
		||||
      case RT_UNTAGGED:
 | 
			
		||||
      case RT_THIS:
 | 
			
		||||
      case RT_MEGAMORPHIC_CACHE_HITS:
 | 
			
		||||
      case RT_CARDS_OFFSET:
 | 
			
		||||
      case RT_DECKS_OFFSET:
 | 
			
		||||
      case RT_EXCEPTION_HANDLER:
 | 
			
		||||
      case RT_INLINE_CACHE_MISS:
 | 
			
		||||
      case RT_SAFEPOINT:
 | 
			
		||||
        return 0;
 | 
			
		||||
      default:
 | 
			
		||||
        critical_error("Bad rel type in number_of_parameters()", rel_type());
 | 
			
		||||
        return -1; /* Can't happen */
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct instruction_operand {
 | 
			
		||||
	relocation_entry rel;
 | 
			
		||||
	code_block *compiled;
 | 
			
		||||
	cell index;
 | 
			
		||||
	cell pointer;
 | 
			
		||||
  relocation_entry rel;
 | 
			
		||||
  code_block* compiled;
 | 
			
		||||
  cell index;
 | 
			
		||||
  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()
 | 
			
		||||
	{
 | 
			
		||||
		return rel.rel_type();
 | 
			
		||||
	}
 | 
			
		||||
  relocation_type rel_type() { return rel.rel_type(); }
 | 
			
		||||
 | 
			
		||||
	cell rel_offset()
 | 
			
		||||
	{
 | 
			
		||||
		return rel.rel_offset();
 | 
			
		||||
	}
 | 
			
		||||
  cell rel_offset() { return rel.rel_offset(); }
 | 
			
		||||
 | 
			
		||||
	fixnum load_value_2_2();
 | 
			
		||||
	fixnum load_value_2_2_2_2();
 | 
			
		||||
	fixnum load_value_masked(cell mask, cell bits, cell shift);
 | 
			
		||||
	fixnum load_value(cell relative_to);
 | 
			
		||||
	fixnum load_value();
 | 
			
		||||
	code_block *load_code_block(cell relative_to);
 | 
			
		||||
	code_block *load_code_block();
 | 
			
		||||
  fixnum load_value_2_2();
 | 
			
		||||
  fixnum load_value_2_2_2_2();
 | 
			
		||||
  fixnum load_value_masked(cell mask, cell bits, cell shift);
 | 
			
		||||
  fixnum load_value(cell relative_to);
 | 
			
		||||
  fixnum load_value();
 | 
			
		||||
  code_block* load_code_block(cell relative_to);
 | 
			
		||||
  code_block* load_code_block();
 | 
			
		||||
 | 
			
		||||
	void store_value_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(fixnum value);
 | 
			
		||||
	void store_code_block(code_block *compiled);
 | 
			
		||||
  void store_value_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(fixnum value);
 | 
			
		||||
  void store_code_block(code_block* compiled);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue