dd6bca2001-07-20Henrik Grubbström (Grubba) Code generation templates for Pike. These paired files should all implement the following functions/macros:
7df3482001-07-21Henrik Grubbström (Grubba) PIKE_OPCODE_T
d8e19a2002-04-07Martin Stjernholm  Type with opcode granularity. This is defined in ../program.h.
7df3482001-07-21Henrik Grubbström (Grubba) 
2f401a2001-07-26Henrik Grubbström (Grubba) PIKE_OPCODE_T *PROG_COUNTER; Return the current program counter.
dd6bca2001-07-20Henrik Grubbström (Grubba) void ins_pointer(INT32 ptr); Store a 32bit pointer at the current offset. INT32 read_pointer(INT32 off); Read a 32bit pointer from the specified offset. void upd_pointer(INT32 off, INT32 ptr); Store a 32bit pointer at the specified offset.
2f401a2001-07-26Henrik Grubbström (Grubba) INT32 LOW_GET_JUMP(void);
f142842003-08-06Martin Stjernholm  Extract a 32bit pointer from the position following this instruction. Note that if OPCODE_RETURN_JUMPADDR is set, the value in PROG_COUNTER typically needs to be offset to compensate for machine code that is after the opcode function call (see JUMP_SET_TO_PC_AT_NEXT).
2f401a2001-07-26Henrik Grubbström (Grubba)  void LOW_SKIPJUMP(void);
f142842003-08-06Martin Stjernholm  Advance PROG_COUNTER past a 32bit pointer. Note that if OPCODE_RETURN_JUMPADDR is set, the value in PROG_COUNTER typically needs to be offset to compensate for machine code that is after the opcode function call (see JUMP_SET_TO_PC_AT_NEXT).
2f401a2001-07-26Henrik Grubbström (Grubba) 
dd6bca2001-07-20Henrik Grubbström (Grubba) void ins_align(INT32 align); Align the current offset to the specified alignment. void ins_byte(INT32 val); Insert an 8bit unsigned value at the current offset. void ins_data(INT32 val); Insert a 32bit value at the current offset.
c81ab42005-11-21Henrik Grubbström (Grubba) INT32 read_program_data(PIKE_OPCODE_T *origin, int offset)
96ccff2005-11-19Henrik Grubbström (Grubba)  Read a data item stored by ins_data. Note that the offset is in number of data units.
dd6bca2001-07-20Henrik Grubbström (Grubba) void ins_f_byte(unsigned int op); Insert the opcode 'op' at the current offset.
9eac532004-03-12Martin Stjernholm  Code to update Pike_fp->pc to point to the current offset should be inserted first, but it's only necessary if the source line or file has changed since the previous opcode. Also, if PIKE_DEBUG is defined and the opcode is completely inlined, then a call to simple_debug_instr_prologue_0 should be inserted before the opcode itself but after the Pike_fp->pc update (if there is any).
dd6bca2001-07-20Henrik Grubbström (Grubba) void ins_f_byte_with_arg(unsigned int op, unsigned INT32 arg); Insert the opcode 'op' with the primary argument 'arg' at
9eac532004-03-12Martin Stjernholm  the current offset. See ins_f_byte for further details.
dd6bca2001-07-20Henrik Grubbström (Grubba)  void ins_f_byte_with_2_args(unsigned int op, unsigned INT32 arg1, unsigned INT32 arg2); Insert the opcode 'op' with the primary argument 'arg1' and
9eac532004-03-12Martin Stjernholm  the secondary argument 'arg2' at the current offset. See ins_f_byte for further details.
dd6bca2001-07-20Henrik Grubbström (Grubba)  void UPDATE_PC(void)
744d352002-04-08Martin Stjernholm  Insert code to update Pike_fp->pc to the current position.
0e0cd72001-07-20Henrik Grubbström (Grubba)  INT32 READ_INCR_BYTE(PIKE_OPCODE_T *pc); Return the byte stored at 'pc' by ins_byte(), and increment 'pc' to the next legal position. Optional macros:
c81ab42005-11-21Henrik Grubbström (Grubba) void INIT_INTERPRETER_STATE(void) Called once during initialization of the interpreter. Typically used to detect and configure CPU specific options. Since it get called after the instrs table has been initialized (but before it has been used), it may alter it.
3eb2b52001-08-03Henrik Grubbström (Grubba) void CALL_MACHINE_CODE(PIKE_OPCODE_T *pc) Start execution of the machine-code located at 'pc'. NOTE: This macro does not return, but instead contains code that returns from the calling context. The value returned in the macro should be one of -1 (inter return), or -2 (inter escape catch).
fd9b662003-03-22Martin Stjernholm void EXIT_MACHINE_CODE() Clean up from CALL_MACHINE_CODE.
44b0702015-05-24Henrik Grubbström (Grubba) int MACHINE_CODE_FORCE_FP() Kludge to force the C compiler to generate a frame for some opcode functions. This is needed for a few machine code backends.
1b07672012-07-18Henrik Grubbström (Grubba) void START_NEW_FUNCTION(int store_lines) Called at the start of a function. store_lines is true for any non-constant evaluation function. This hook can be used to add common helper subroutines and/or reset code-generator state. void END_FUNCTION(int store_lines) Called after all f-codes for a function have been emitted. Typically used to clean up after START_NEW_FUNCTION(). store_lines will contain the same value as when START_NEW_FUNCTION() was called.
2f401a2001-07-26Henrik Grubbström (Grubba) void SET_PROG_COUNTER(PIKE_OPCODE_T *newpc) Set PROG_COUNTER to a new value.
58bc3d2003-08-07Martin Stjernholm GLOBAL_DEF_PROG_COUNTER; Declare stuff that is needed for PROG_COUNTER at the global level in the interpreter.
2f401a2001-07-26Henrik Grubbström (Grubba) DEF_PROG_COUNTER;
58bc3d2003-08-07Martin Stjernholm  Declare stuff that is needed for PROG_COUNTER in each opcode function.
2f401a2001-07-26Henrik Grubbström (Grubba)  int PIKE_OPCODE_ALIGN; Alignment restriction for PIKE_OPCODE_T (debug).
096c392001-07-24Henrik Grubbström (Grubba) void INS_ENTRY(void) Mark the entry point from eval_instruction().
15910a2012-04-09Henrik Grubbström (Grubba)  Useful to add startup code. Note that this in turn will typically require use of OPCODE_INLINE_RETURN.
096c392001-07-24Henrik Grubbström (Grubba) 
1c9ebc2001-07-24Henrik Grubbström (Grubba) int ENTRY_PROLOGUE_SIZE
f13d302006-02-27Martin Stjernholm  Size (in opcodes) of the prologue inserted by INS_ENTRY, which
15910a2012-04-09Henrik Grubbström (Grubba)  should be skipped e.g. when tail recursing. Required when INS_ENTRY is used.
1c9ebc2001-07-24Henrik Grubbström (Grubba) 
0e0cd72001-07-20Henrik Grubbström (Grubba) void RELOCATE_program(struct program *p, PIKE_OPCODE_T *new); Relocate the copy of 'p'->program at 'new' to be able to execute at the new position. void FLUSH_INSTRUCTION_CACHE(void *addr, size_t len); Flush the memory at 'addr' from the instruction cache.
697e0a2001-07-20Henrik Grubbström (Grubba)  void ENCODE_PROGRAM(struct program *p, struct dynamic_buffer_s *buf); Encode 'p'->program in a way accepted by DECODE_PROGRAM(). NOTE: The encoded data MUST have the length p->num_program * sizeof(PIKE_OPCODE_T). void DECODE_PROGRAM(struct program *p) Decode 'p'->program as encoded by ENCODE_PROGRAM(). NOTE: 'p'->relocations is valid at this point.
80fe612001-07-21Fredrik Hübinette (Hubbe) 
379ea02001-07-24Henrik Grubbström (Grubba) void FLUSH_CODE_GENERATOR_STATE(void)
80fe612001-07-21Fredrik Hübinette (Hubbe)  Called at labels and beginning of functions to notify the code generator that registers and other states must be updated at this point.
2779f52002-05-11Martin Stjernholm void ADJUST_PIKE_PC(PIKE_OPCODE_T *pc) Called after opcodes that modify Pike_fp->pc. The passed argument is the pc they will put there. Useful when UPDATE_PC
9eac532004-03-12Martin Stjernholm  inserts code that update Pike_fp->pc relatively. (Note: Not used anymore.)
2779f52002-05-11Martin Stjernholm 
852c152001-07-23Fredrik Hübinette (Hubbe) int ALIGN_PIKE_JUMPS This can be defined to a number which will cause Pike to insert zeroes in the code after instructions which do not return to permit better alignment of code. Please note that this is not guaranteed and should only be used for optimization. int ALIGN_PIKE_FUNCTION_BEGINNINGS
2779f52002-05-11Martin Stjernholm  Similar to ALIGN_PIKE_JUMPS, but only for the beginning
f142842003-08-06Martin Stjernholm  of a function.
852c152001-07-23Fredrik Hübinette (Hubbe) 
142b002003-11-25Martin Stjernholm int INS_F_JUMP(unsigned int op, int backward_jump)
f142842003-08-06Martin Stjernholm  Similar to ins_f_byte, but is only called for jump and branch instructions that take a constant target address. The return value should be the offset in the program to the empty address field of the jump instruction, which will be filled in by UPDATE_F_JUMP. You can also return -1 to make the code use the same behaviour as if INS_F_JUMP was not defined.
1a9a8f2001-08-17Marcus Comstedt 
142b002003-11-25Martin Stjernholm  backward_jump is only relevant for branch opcodes if OPCODE_INLINE_BRANCH is defined. If it's set, a call to branch_check_threads_etc should be compiled in whenever the branch is taken. int INS_F_JUMP_WITH_ARG(unsigned int op, unsigned INT32 arg, int backward_jump)
f142842003-08-06Martin Stjernholm  Similar to INS_F_JUMP(), but called for instructions that take
142b002003-11-25Martin Stjernholm  one parameter.
3344892002-11-02Henrik Grubbström (Grubba) 
f142842003-08-06Martin Stjernholm int INS_F_JUMP_WITH_TWO_ARGS(unsigned int op,
3344892002-11-02Henrik Grubbström (Grubba)  unsigned INT32 arg1,
142b002003-11-25Martin Stjernholm  unsigned INT32 arg2, int backward_jump)
f142842003-08-06Martin Stjernholm  Similar to INS_F_JUMP(), but called for instructions that take two parameters.
3344892002-11-02Henrik Grubbström (Grubba) 
f142842003-08-06Martin Stjernholm void UPDATE_F_JUMP(INT32 offset, INT32 to_offset) If you define any of the INS_F_JUMP* functions you must also define this one. It's called when the compiler knows where to jump. (See ia32.c for an example of this and INS_F_JUMP.) INT32 READ_F_JUMP(INT32 offset) If you define any of the INS_F_JUMP* functions you must also define this one. It's called when the compiler needs to read back the to_offset that was passed to UPDATE_F_JUMP.
9450432002-11-02Henrik Grubbström (Grubba)  OPCODE_INLINE_BRANCH
f142842003-08-06Martin Stjernholm  If defined, test functions that return nonzero when the branch
9450432002-11-02Henrik Grubbström (Grubba)  is to be taken will be generated for I_BRANCH instructions.
f142842003-08-06Martin Stjernholm  The machine code generated by INS_F_JUMP* must test the return value for those opcodes and jump iff it's nonzero. This is to facilitate easier inlining of branches in the machine code.
4555f32011-05-11Henrik Grubbström (Grubba) OPCODE_INLINE_RETURN If defined, opcode functions that perform INTER_RETURN will return (void *)(ptrdiff_t)-1 when they want to exit from the running interpreter. These opcodes also have the I_RETURN flag set. This is to facilitate easier use of and clean up of INS_ENTRY().
f142842003-08-06Martin Stjernholm OPCODE_RETURN_JUMPADDR If defined, jump functions that return the address to jump to will be generated for I_JUMP instructions, so the ins_f_byte* must generate machine code that (unconditionally) jumps to the return value for those opcodes. If this isn't defined, they will instead use SET_PROG_COUNTER to change the address they return to. This macro allows faster code on cpus where setting the return address wreaks havoc in the instruction pipelines. JUMP_SET_TO_PC_AT_NEXT(PIKE_OPCODE_T *PC) Used in I_JUMP opcodes to store the pc to the next instruction, to compensate for any machine code that is inserted after the call. PC is the lvalue where it should be stored. Must be defined if OPCODE_RETURN_JUMPADDR is. void CHECK_RELOC(size_t reloc, size_t program_size) Check if a relocation is valid for the program. Should throw an error on bad relocations.
1633152002-11-07Henrik Grubbström (Grubba) 
15910a2012-04-09Henrik Grubbström (Grubba) void DISASSEMBLE_CODE(void *addr, size_t bytes)
1633152002-11-07Henrik Grubbström (Grubba)  Debug function that dumps the generated code on stderr.
15910a2012-04-09Henrik Grubbström (Grubba)  Help structures and functions implemented in other places: struct instr instrs[]; Array of bytecode instruction definitions. Indexed by F-opcode minus F_OFFSET. See opcodes.h for details. PIKE_OPCODE_T *inter_return_opcode_F_CATCH(PIKE_OPCODE_T *addr) Function to simplify implementation of F_CATCH in OPCODE_INLINE_RETURN mode. See interpret.c for details.