diff --git a/vm/instruction_operands.cpp b/vm/instruction_operands.cpp index 7b7802297a..57d248c260 100644 --- a/vm/instruction_operands.cpp +++ b/vm/instruction_operands.cpp @@ -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()); } } diff --git a/vm/instruction_operands.hpp b/vm/instruction_operands.hpp index 4ae364e78d..3260311174 100644 --- a/vm/instruction_operands.hpp +++ b/vm/instruction_operands.hpp @@ -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); }; }