| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | namespace factor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-02 12:11:34 -05:00
										 |  |  | inline static void* frame_return_address(void *frame_top) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return *(void**)frame_top; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-05 17:18:42 -05:00
										 |  |  | inline static void set_frame_return_address(void *frame_top, void *return_address) | 
					
						
							| 
									
										
										
										
											2011-12-02 12:11:34 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-05 17:18:42 -05:00
										 |  |  | 	*(void**)frame_top = return_address; | 
					
						
							| 
									
										
										
										
											2011-12-02 12:11:34 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-06 20:53:52 -05:00
										 |  |  | #define CALLSTACK_BOTTOM(ctx) (void *)(ctx->callstack_seg->end - sizeof(cell) * 5)
 | 
					
						
							| 
									
										
										
										
											2010-03-26 22:44:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | inline static void flush_icache(cell start, cell len) {} | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-06 23:44:30 -04:00
										 |  |  | /* In the instruction sequence:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    MOV EBX,... | 
					
						
							|  |  |  |    JMP blah | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    the offset from the immediate operand to MOV to the instruction after | 
					
						
							|  |  |  |    the jump is a cell for the immediate operand, 4 bytes for the JMP | 
					
						
							|  |  |  |    destination, and one byte for the JMP opcode. */ | 
					
						
							| 
									
										
										
										
											2010-01-02 07:03:30 -05:00
										 |  |  | static const fixnum xt_tail_pic_offset = 4 + 1; | 
					
						
							| 
									
										
										
										
											2009-05-06 23:04:01 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-06 20:22:22 -04:00
										 |  |  | static const unsigned char call_opcode = 0xe8; | 
					
						
							|  |  |  | static const unsigned char jmp_opcode = 0xe9; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline static unsigned char call_site_opcode(cell return_address) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return *(unsigned char *)(return_address - 5); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | inline static void check_call_site(cell return_address) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-06 20:22:22 -04:00
										 |  |  | 	unsigned char opcode = call_site_opcode(return_address); | 
					
						
							| 
									
										
										
										
											2011-11-17 23:42:30 -05:00
										 |  |  | 	FACTOR_ASSERT(opcode == call_opcode || opcode == jmp_opcode); | 
					
						
							| 
									
										
										
										
											2011-11-23 01:51:54 -05:00
										 |  |  | 	(void)opcode; // suppress warning when compiling without assertions
 | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | inline static void *get_call_target(cell return_address) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	check_call_site(return_address); | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	return (void *)(*(int *)(return_address - 4) + return_address); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | inline static void set_call_target(cell return_address, void *target) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	check_call_site(return_address); | 
					
						
							| 
									
										
										
										
											2010-01-24 08:17:18 -05:00
										 |  |  | 	*(int *)(return_address - 4) = (u32)((cell)target - return_address); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-06 20:22:22 -04:00
										 |  |  | inline static bool tail_call_site_p(cell return_address) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-15 07:20:09 -05:00
										 |  |  | 	switch(call_site_opcode(return_address)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case jmp_opcode: return true; | 
					
						
							|  |  |  | 	case call_opcode: return false; | 
					
						
							|  |  |  | 	default: abort(); return false; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-05-06 20:22:22 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 00:37:28 -04:00
										 |  |  | inline static unsigned int fpu_status(unsigned int status) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-06 02:06:26 -05:00
										 |  |  | 	unsigned int r = 0; | 
					
						
							| 
									
										
										
										
											2009-09-14 04:09:03 -04:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-02-06 02:06:26 -05:00
										 |  |  | 	if (status & 0x01) | 
					
						
							| 
									
										
										
										
											2009-09-14 04:09:03 -04:00
										 |  |  | 		r |= FP_TRAP_INVALID_OPERATION; | 
					
						
							| 
									
										
										
										
											2010-02-06 02:06:26 -05:00
										 |  |  | 	if (status & 0x04) | 
					
						
							| 
									
										
										
										
											2009-09-14 04:09:03 -04:00
										 |  |  | 		r |= FP_TRAP_ZERO_DIVIDE; | 
					
						
							| 
									
										
										
										
											2010-02-06 02:06:26 -05:00
										 |  |  | 	if (status & 0x08) | 
					
						
							| 
									
										
										
										
											2009-09-14 04:09:03 -04:00
										 |  |  | 		r |= FP_TRAP_OVERFLOW; | 
					
						
							| 
									
										
										
										
											2010-02-06 02:06:26 -05:00
										 |  |  | 	if (status & 0x10) | 
					
						
							| 
									
										
										
										
											2009-09-14 04:09:03 -04:00
										 |  |  | 		r |= FP_TRAP_UNDERFLOW; | 
					
						
							| 
									
										
										
										
											2010-02-06 02:06:26 -05:00
										 |  |  | 	if (status & 0x20) | 
					
						
							| 
									
										
										
										
											2009-09-14 04:09:03 -04:00
										 |  |  | 		r |= FP_TRAP_INEXACT; | 
					
						
							| 
									
										
										
										
											2009-09-14 00:37:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-06 02:06:26 -05:00
										 |  |  | 	return r; | 
					
						
							| 
									
										
										
										
											2009-09-14 00:37:28 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |