e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
dd6bca2001-07-20Henrik Grubbström (Grubba) 
2f401a2001-07-26Henrik Grubbström (Grubba) #define PIKE_OPCODE_ALIGN 4
58c2442005-06-17Henrik Grubbström (Grubba) #if defined(__arch64__) || defined(__sparcv9) #define PIKE_BYTECODE_SPARC64 #endif
92bea02008-05-03Marcus Comstedt #define REGISTER_ASSIGN(R,V) ({__asm__ (""::"r"(R=(V))); R;})
2f401a2001-07-26Henrik Grubbström (Grubba) #define DEF_PROG_COUNTER register unsigned INT32 *reg_pc __asm__ ("%i7")
4aab382003-08-07Martin Stjernholm #define GLOBAL_DEF_PROG_COUNTER DEF_PROG_COUNTER
2f401a2001-07-26Henrik Grubbström (Grubba) #define PROG_COUNTER (reg_pc + 2)
92bea02008-05-03Marcus Comstedt #define SET_PROG_COUNTER(X) REGISTER_ASSIGN(reg_pc, ((unsigned INT32 *)(X))-2)
2f401a2001-07-26Henrik Grubbström (Grubba) 
8c01312005-07-05Henrik Grubbström (Grubba) #define LOW_GET_JUMP() ((INT32)PROG_COUNTER[0])
a53c282005-06-21Henrik Grubbström (Grubba) #define LOW_SKIPJUMP() (SET_PROG_COUNTER(PROG_COUNTER + 1))
2f401a2001-07-26Henrik Grubbström (Grubba) 
0dc1b72002-11-06Henrik Grubbström (Grubba) /* * Code generator state. */ extern unsigned INT32 sparc_codegen_state;
58c2442005-06-17Henrik Grubbström (Grubba) extern ptrdiff_t sparc_last_pc;
0dc1b72002-11-06Henrik Grubbström (Grubba) 
aaf6d32002-11-08Henrik Grubbström (Grubba) #define SPARC_CODEGEN_FP_IS_SET 1 #define SPARC_CODEGEN_SP_IS_SET 2 #define SPARC_CODEGEN_IP_IS_SET 4 #define SPARC_CODEGEN_PC_IS_SET 8 #define SPARC_CODEGEN_MARK_SP_IS_SET 16 #define SPARC_CODEGEN_SP_NEEDS_STORE 32 #define SPARC_CODEGEN_MARK_SP_NEEDS_STORE 64
0dc1b72002-11-06Henrik Grubbström (Grubba) 
a970e52002-11-08Henrik Grubbström (Grubba) void sparc_flush_codegen_state(void); #define FLUSH_CODE_GENERATOR_STATE() sparc_flush_codegen_state()
0dc1b72002-11-06Henrik Grubbström (Grubba) 
4f43322002-11-05Henrik Grubbström (Grubba) /* Size of the prologue added by INS_ENTRY() (in PIKE_OPCODE_T's). */
1c9ebc2001-07-24Henrik Grubbström (Grubba) #define ENTRY_PROLOGUE_SIZE 1
4f43322002-11-05Henrik Grubbström (Grubba) void sparc_ins_entry(void); #define INS_ENTRY() sparc_ins_entry() void sparc_update_pc(void); #define UPDATE_PC() sparc_update_pc()
ece7262001-07-20Henrik Grubbström (Grubba)  #define ins_pointer(PTR) add_to_program((INT32)(PTR)) #define read_pointer(OFF) (Pike_compiler->new_program->program[(INT32)(OFF)]) #define upd_pointer(OFF,PTR) (Pike_compiler->new_program->program[(INT32)(OFF)] = (INT32)(PTR))
58c2442005-06-17Henrik Grubbström (Grubba) 
ece7262001-07-20Henrik Grubbström (Grubba) #define ins_align(ALIGN) #define ins_byte(VAL) add_to_program((INT32)(VAL)) #define ins_data(VAL) add_to_program((INT32)(VAL))
c81ab42005-11-21Henrik Grubbström (Grubba) #define read_program_data(PTR, OFF) ((INT32)((PTR)[OFF]))
0e0cd72001-07-20Henrik Grubbström (Grubba)  #define READ_INCR_BYTE(PC) (((PC)++)[0]) #define RELOCATE_program(P, NEW) do { \ PIKE_OPCODE_T *op_ = NEW; \ struct program *p_ = P; \ size_t rel_ = p_->num_relocations; \ INT32 delta_ = p_->program - op_; \ while (rel_--) { \ DO_IF_DEBUG( \ if ((op_[p_->relocations[rel_]] & 0xc0000000) != \ 0x40000000) { \
5aad932002-08-15Marcus Comstedt  Pike_fatal("Bad relocation: %d, off:%d, opcode: 0x%08x\n", \
0e0cd72001-07-20Henrik Grubbström (Grubba)  rel_, p_->relocations[rel_], \ op_[p_->relocations[rel_]]); \ } \ ); \ op_[p_->relocations[rel_]] = 0x40000000| \ (((op_[p_->relocations[rel_]] & 0x3fffffff) + delta_) & \ 0x3fffffff); \ } \ } while(0)
9d2e2d2001-07-21Henrik Grubbström (Grubba) extern const unsigned INT32 sparc_flush_instruction_cache[];
a861e12004-04-20Jakub Bogusz #define FLUSH_INSTRUCTION_CACHE(ADDR, LEN) \ (((void (*)(void *,size_t))sparc_flush_instruction_cache) \ (ADDR, (LEN)+sizeof(PIKE_OPCODE_T)))
697e0a2001-07-20Henrik Grubbström (Grubba) 
2d10fb2016-12-29Arne Goedeke struct byte_buffer;
697e0a2001-07-20Henrik Grubbström (Grubba) 
44b0702015-05-24Henrik Grubbström (Grubba) #define MACHINE_CODE_FORCE_FP() sparc_force_fp() int sparc_force_fp(void);
2d10fb2016-12-29Arne Goedeke void sparc_encode_program(struct program *p, struct byte_buffer *buf);
697e0a2001-07-20Henrik Grubbström (Grubba) void sparc_decode_program(struct program *p); #define ENCODE_PROGRAM(P, BUF) sparc_encode_program(P, BUF) #define DECODE_PROGRAM(P) sparc_decode_program(p)
f5e8622002-11-07Henrik Grubbström (Grubba)  void sparc_disassemble_code(void *addr, size_t bytes); #define DISASSEMBLE_CODE(ADDR, BYTES) sparc_disassemble_code(ADDR, BYTES)
aadf3c2006-03-15Henrik Grubbström (Grubba)  #ifdef PIKE_DEBUG #define CALL_MACHINE_CODE(pc) \ do { \ /* The test is needed to get the labels to work... */ \ if (pc) { \ if ((((PIKE_OPCODE_T *)pc)[0] & 0x81e02000) != \ 0x81e02000) \ Pike_fatal("Machine code at %p lacking F_ENTRY!\n", \ pc); \ return ((int (*)(void))(pc))(); \ } \ } while(0) #endif /* !PIKE_DEBUG */
73701e2009-11-21Marcus Comstedt  #ifdef __GNUC__ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) /* Avoid an overoptimization bug in gcc 4.3.4 which caused the address * stored in do_inter_return_label to be at the CALL_MACHINE_CODE line. */ #define EXIT_MACHINE_CODE() do { __asm__ __volatile__(""); } while(0) #endif #endif