| 
									
										
										
										
											2013-05-11 22:06:39 -04:00
										 |  |  | namespace factor { | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | enum relocation_type { | 
					
						
							| 
									
										
										
										
											2013-05-11 22:06:39 -04:00
										 |  |  |   /* 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
 | 
					
						
							| 
									
										
										
										
											2011-09-14 04:08:32 -04:00
										 |  |  | 	relocation to reduce compile time and size for PICs. */ | 
					
						
							| 
									
										
										
										
											2013-05-11 22:06:39 -04:00
										 |  |  |   RT_INLINE_CACHE_MISS, | 
					
						
							|  |  |  |   /* address of safepoint page in code heap */ | 
					
						
							|  |  |  |   RT_SAFEPOINT | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | enum relocation_class { | 
					
						
							| 
									
										
										
										
											2013-05-11 22:06:39 -04:00
										 |  |  |   /* 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, | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-20 18:11:50 -04:00
										 |  |  | 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; | 
					
						
							| 
									
										
										
										
											2013-05-11 22:06:39 -04:00
										 |  |  | static const cell rel_indirect_arm_mask = 0x00000fff; | 
					
						
							| 
									
										
										
										
											2011-05-20 18:11:50 -04:00
										 |  |  | static const cell rel_relative_arm_3_mask = 0x00ffffff; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* code relocation table consists of a table of entries for each fixup */ | 
					
						
							| 
									
										
										
										
											2009-11-07 17:16:09 -05:00
										 |  |  | struct relocation_entry { | 
					
						
							| 
									
										
										
										
											2013-05-13 00:28:25 -04:00
										 |  |  |   uint32_t value; | 
					
						
							| 
									
										
										
										
											2013-05-11 22:06:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-13 00:28:25 -04:00
										 |  |  |   explicit relocation_entry(uint32_t value) : value(value) {} | 
					
						
							| 
									
										
										
										
											2013-05-11 22:06:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   relocation_entry(relocation_type rel_type, relocation_class rel_class, | 
					
						
							|  |  |  |                    cell offset) { | 
					
						
							| 
									
										
										
										
											2013-05-13 00:28:25 -04:00
										 |  |  |     value = (uint32_t)((rel_type << 28) | (rel_class << 24) | offset); | 
					
						
							| 
									
										
										
										
											2013-05-11 22:06:39 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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 */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-07 17:16:09 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-23 19:51:08 -05:00
										 |  |  | struct instruction_operand { | 
					
						
							| 
									
										
										
										
											2013-05-11 22:06:39 -04:00
										 |  |  |   relocation_entry rel; | 
					
						
							|  |  |  |   code_block* compiled; | 
					
						
							|  |  |  |   cell index; | 
					
						
							|  |  |  |   cell pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-12 23:20:43 -04:00
										 |  |  |   instruction_operand(relocation_entry rel, code_block* compiled, | 
					
						
							|  |  |  |                       cell index); | 
					
						
							| 
									
										
										
										
											2013-05-11 22:06:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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); | 
					
						
							| 
									
										
										
										
											2009-11-07 17:16:09 -05:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |