#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;
-
- 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_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;
+ }
}
-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());
}
}
-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;
-
- 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_type rel_type()
- {
- return (relocation_type)((value & 0xf0000000) >> 28);
- }
-
- relocation_class rel_class()
- {
- return (relocation_class)((value & 0x0f000000) >> 24);
- }
-
- 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 */
- }
- }
+ u32 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_type rel_type() {
+ return (relocation_type)((value & 0xf0000000) >> 28);
+ }
+
+ relocation_class rel_class() {
+ return (relocation_class)((value & 0x0f000000) >> 24);
+ }
+
+ 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 */
+ }
+ }
};
struct instruction_operand {
- relocation_entry rel;
- code_block *compiled;
- cell index;
- cell pointer;
-
- instruction_operand(relocation_entry rel_, code_block *compiled_, cell index_);
-
- relocation_type rel_type()
- {
- return rel.rel_type();
- }
-
- 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();
-
- 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);
+ relocation_entry rel;
+ code_block* compiled;
+ cell index;
+ cell pointer;
+
+ instruction_operand(relocation_entry rel_, code_block* compiled_,
+ cell index_);
+
+ relocation_type rel_type() { return rel.rel_type(); }
+
+ 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();
+
+ 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);
};
}