2 * $Id: xlat.h 931 2008-10-31 02:57:59Z nkeynes $
4 * Internal translation data structures and functions.
6 * Copyright (c) 2009 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 #ifndef lxdream_xlat_H
20 #define lxdream_xlat_H 1
22 #include "xlat/xiropt.h"
23 #include "xlat/xltcache.h"
25 typedef struct target_data *target_data_t;
28 * Source machine description. This should be immutable once constructed.
30 struct xlat_source_machine {
32 void *state_data; /* Pointer to source machine state structure */
33 const char **reg_names; /* Register names, indexed by offset/4 */
34 uint32_t pc_offset; /* Offset of source PC, relative to state_data */
35 uint32_t delayed_pc_offset; /* Offset of source delayed PC offset, relative to state_data */
36 uint32_t t_offset; /* Offset of source T reg, relative to state_data */
42 * Decode a basic block of instructions from start, stopping after a
43 * control transfer or before the given end instruction.
44 * @param sd source data. This method should set the address_space field.
45 * @return the pc value after the last decoded instruction.
47 uint32_t (*decode_basic_block)(xir_basic_block_t xbb);
51 /* Target machine description (no these are not meant to be symmetrical) */
52 struct xlat_target_machine {
54 /* Register information */
55 const char **reg_names;
57 /* Required functions */
60 * Test if the given operands are legal for the opcode. Note that it is assumed that
61 * target register operands are always legal. This is used by the register allocator
62 * to determine when it can fuse load/stores with another operation.
64 gboolean (*is_legal)( xir_opcode_t op, xir_operand_type_t arg0, xir_operand_type_t arg1 );
67 * Lower IR closer to the machine, handling machine-specific issues that can't
68 * wait until final code-gen. Can add additional instructions where required.
70 void (*lower)( xir_basic_block_t xbb, xir_op_t begin, xir_op_t end );
73 * Determine the memory required to emit code for the specified block excluding
74 * exceptions. This can be an overestimate,
75 * as long as it is at least large enough for the final code.
76 * @param begin start of code block
77 * @param end end of code block
78 * @return estimated size of emitted code.
80 uint32_t (*get_code_size)( xir_op_t begin, xir_op_t end );
83 * Final target code generation.
84 * @param td target_data information.
85 * @param begin start of code block
86 * @param end end of code block
87 * @param exception_table Table of pointers to exception code
88 * @return number of bytes actually emitted.
90 uint32_t (*codegen)( target_data_t td, xir_op_t begin, xir_op_t end );
95 * Fixup records generated while assembling the code. Records are one of the
97 * Constant (32 or 64-bit)
98 * Exception (from a memory call or RAISEME instruction)
100 * Relocations may be 32/64 bit absolute or 32-bit PC-relative. The value in the
101 * relocation cell is taken as the addend if nonzero. For relative relocations,
102 * the relative displacement is calculated from the end of the fixup value -
103 * that is, for a REL32, the result will be
104 * *fixup_loc += &target - (fixup_loc+4)
106 * In principle we could use a global constant table, but that adds complexity
110 #define TARGET_FIXUP_CONST32 0x00
111 #define TARGET_FIXUP_CONST64 0x01
112 #define TARGET_FIXUP_RAISE 0x02
113 #define TARGET_FIXUP_RAISEEXT 0x03 /* An exception that can be raised from outside the generated code */
114 #define TARGET_FIXUP_OFFSET 0x04 /* Offset within the code block */
115 #define TARGET_FIXUP_POINTER 0x05 /* Absolute pointer */
117 #define TARGET_FIXUP_ABS32 0x00
118 #define TARGET_FIXUP_ABS64 0x10
119 #define TARGET_FIXUP_REL32 0x20
120 #define TARGET_FIXUP_REL64 0x30
122 #define TARGET_FIXUP_TARGET(x) ((x)&0x0F)
123 #define TARGET_FIXUP_MODE(x) ((x)&0xF0)
125 typedef struct target_fixup_struct {
126 int fixup_type; /* Combination of TARGET_FIXUP flags above */
127 uint32_t fixup_offset; /* Location of fixup (to be modified) relative to start of block */
128 uint32_t target_offset;
140 * Temporary data maintained during code generation
143 struct xlat_target_machine *mach;
144 struct xlat_source_macine *src;
145 xlat_cache_block_t block;
146 uint8_t *xlat_output;
147 target_fixup_t fixup_table;
148 int fixup_table_posn;
149 int fixup_table_size;
152 /** Add fixup to a 32-bit constant memory value, adding the value to the constant table */
153 void target_add_const32_fixup( target_data_t td, int mode, void *location, uint32_t i );
154 /** Add fixup to a 64-bit constant memory value, adding the value to the constant table */
155 void target_add_const64_fixup( target_data_t td, int mode, void *location, uint64_t i );
156 /** Add fixup to an internal exception handler block */
157 void target_add_raise_fixup( target_data_t td, int type, void *location, xir_op_t *exc );
158 /** Add fixup to an externally accessible exception handle block */
159 void target_add_raiseext_fixup( target_data_t td, int type, void *location, xir_op_t *exc );
160 /** Add fixup to an arbitrary offset within the code block */
161 void target_add_offset_fixup( target_data_t td, int type, void *location, uint32_t off );
162 /** Add fixup to an arbitrary pointer */
163 void target_add_pointer_fixup( target_data_t td, int type, void *location, void *p );
166 * Generate final code for the block.
167 * @return entry point of the code block.
169 void *target_codegen( xlat_target_machine_t target, xir_basic_block_t xbb );
171 #endif /* lxdream_xlat_H */
.