|
TPDE
|
Compiler mixin for targeting x86-64. More...
#include <CompilerX64.hpp>
Classes | |
| class | CallBuilder |
| Helper class for building call sequences. More... | |
Public Types | |
| enum class | Jump { jo = 0 , jno , jb , jae , je , jne , jbe , ja , js , jns , jp , jnp , jl , jge , jle , jg , jmp } |
| Jump conditions. More... | |
Public Member Functions | |
| void | prologue_begin (CCAssigner *cc_assigner) noexcept |
| Begin prologue, prepare for assigning arguments. | |
| std::optional< i32 > | prologue_assign_arg_part (ValuePart &&vp, CCAssignment cca) noexcept |
| Assign argument part. | |
| void | prologue_end (CCAssigner *cc_assigner) noexcept |
| Finish prologue. | |
| void | alloca_fixed (u64 size, u32 align, ValuePart &res) noexcept |
| Dynamic alloca of a fixed-size region. | |
| void | alloca_dynamic (u64 elem_size, ValuePart &&count, u32 align, ValuePart &res) noexcept |
| Dynamic alloca of a dynamically-sized region (elem_size * count bytes). | |
| void | materialize_constant (const u64 *data, RegBank bank, u32 size, AsmReg dst) noexcept |
| Materialize constant into a register. | |
| void | generate_raw_jump (Jump jmp, Label target) noexcept |
| Generate jump instruction to target label. | |
| void | generate_raw_set (Jump cc, AsmReg dst, bool zext=true) noexcept |
| Set dst to 1 if cc is true, otherwise set it to zero. | |
| void | generate_raw_mask (Jump cc, AsmReg dst) noexcept |
| Set all bits of dst to 1 if cc is true, otherwise set it to zero. | |
| void | generate_raw_cmov (Jump cc, AsmReg dst, AsmReg src, bool is_64) noexcept |
| Move src into dst if cc is true, otherwise do nothing. | |
| void | generate_raw_intext (AsmReg dst, AsmReg src, bool sign, u32 from, u32 to) noexcept |
| Integer extension. | |
| void | generate_raw_bfi (AsmReg dst, AsmReg src, u32 lsb, u32 width) noexcept |
| Bitfield insert. Needs a temporary register, src is not modified. | |
| void | generate_raw_bfiz (AsmReg dst, AsmReg src, u32 lsb, u32 width) noexcept |
| Bitfield insert in zero. | |
| void | generate_call (std::variant< SymRef, ValuePart > &&target, std::span< CallArg > arguments, typename Base::ValueRef *result, bool variable_args=false) |
| Generate a function call. | |
| ScratchReg | tls_get_addr (SymRef sym, TLSModel model) noexcept |
| Generate code sequence to load address of sym into a register. | |
Public Member Functions inherited from tpde::CompilerBase< Adaptor, Derived, PlatformConfig > | |
| CompilerBase (Adaptor *adaptor) | |
| Initialize a CompilerBase, should be called by the derived classes. | |
| Derived * | derived () |
| shortcut for casting to the Derived class so that overloading works | |
| bool | compile () |
| Compile the functions returned by Adaptor::funcs. | |
| void | reset () |
| Reset any leftover data from the previous compilation such that it will not affect the next compilation. | |
| CCAssigner * | cur_cc_assigner () noexcept |
| Get CCAssigner for current function. | |
| void | release_assignment (ValLocalIdx local_idx, ValueAssignment *) noexcept |
| Release an assignment when reference count drops to zero, either frees the assignment immediately or delays free to the end of the live range. | |
| void | init_variable_ref (ValLocalIdx local_idx, u32 var_ref_data) noexcept |
| Init a variable-ref assignment. | |
| void | init_variable_ref (IRValueRef value, u32 var_ref_data) noexcept |
| Init a variable-ref assignment. | |
| void | prologue_assign_arg (CCAssigner *cc_assigner, u32 arg_idx, IRValueRef arg, u32 align=1, bool allow_split=false) noexcept |
| Assign function argument in prologue. | |
| AsmReg | gval_as_reg (GenericValuePart &gv) noexcept |
| Get generic value part into a single register, evaluating expressions and materializing immediates as required. | |
| AsmReg | gval_as_reg_reuse (GenericValuePart &gv, ScratchReg &dst) noexcept |
| Like gval_as_reg; if the GenericValuePart owns a reusable register (either a ScratchReg, possibly due to materialization, or a reusable ValuePartRef), store it in dst. | |
| void | label_place (Label label) noexcept |
| Convenience function to place a label at the current position. | |
| i32 | allocate_stack_slot (u32 size) noexcept |
| Allocate a static stack slot. | |
| void | free_stack_slot (u32 slot, u32 size) noexcept |
| Free a static stack slot. | |
| ValueRef | val_ref (IRValueRef value) noexcept |
| Get a using reference to a value. | |
| std::pair< ValueRef, ValuePartRef > | val_ref_single (IRValueRef value) noexcept |
| Get a using reference to a single-part value and provide direct access to the only part. | |
| ValueRef | result_ref (IRValueRef value) noexcept |
| Get a defining reference to a value. | |
| std::pair< ValueRef, ValuePartRef > | result_ref_single (IRValueRef value) noexcept |
| Get a defining reference to a single-part value and provide direct access to the only part. | |
| ValueRef | result_ref_alias (IRValueRef dst, ValueRef &&src) noexcept |
| Make dst an alias for src, which must be a non-constant value with an identical part configuration. | |
| ValueRef | result_ref_stack_slot (IRValueRef value, AssignmentPartRef base, i32 off) noexcept |
| Initialize value as a pointer into a stack variable (i.e., a value allocated from cur_static_allocas() or similar) with an offset. | |
| Reg | select_reg (RegBank bank, u64 exclusion_mask) noexcept |
| Select an available register, evicting loaded values if needed. | |
| void | reload_to_reg (AsmReg dst, AssignmentPartRef ap) noexcept |
| Reload a value part from memory or recompute variable address. | |
| void | allocate_spill_slot (AssignmentPartRef ap) noexcept |
| Allocate a stack slot for an assignment. | |
| void | spill (AssignmentPartRef ap) noexcept |
| Ensure the value is spilled in its stack slot (except variable refs). | |
| void | evict (AssignmentPartRef ap) noexcept |
| Evict the value from its register, spilling if needed, and free register. | |
| void | evict_reg (Reg reg) noexcept |
| Evict the value from the register, spilling if needed, and free register. | |
| void | free_reg (Reg reg) noexcept |
| Free the register. Requires that the contained value is already spilled. | |
| void | generate_uncond_branch (IRBlockRef target) noexcept |
| Generate an unconditional branch at the end of a basic block. | |
| void | generate_cond_branch (Jump jmp, IRBlockRef true_target, IRBlockRef false_target) noexcept |
| Generate an conditional branch at the end of a basic block. | |
| void | generate_switch (ScratchReg &&cond, u32 width, IRBlockRef default_block, std::span< const std::pair< u64, IRBlockRef > > cases) noexcept |
| Generate a switch at the end of a basic block. | |
| RegisterFile::RegBitSet | spill_before_branch (bool force_spill=false) noexcept |
| Spill values that need to be spilled for later blocks. | |
| void | release_spilled_regs (typename RegisterFile::RegBitSet) noexcept |
| Free registers marked by spill_before_branch(). | |
| void | release_regs_after_return () noexcept |
| When reaching a point in the function where no other blocks will be reached anymore, use this function to release register assignments after the end of that block so the compiler does not accidentally use registers which don't contain any values. | |
| void | begin_branch_region () noexcept |
| Indicate beginning of region where value-state must not change. | |
| void | end_branch_region () noexcept |
| Indicate end of region where value-state must not change. | |
| void | generate_branch_to_block (Jump jmp, IRBlockRef target, bool needs_split, bool last_inst) noexcept |
| Generate a branch to a basic block; execution continues afterwards. | |
| bool | branch_needs_split (IRBlockRef target) noexcept |
| Whether branch to a block requires additional instructions and therefore a direct jump to the block is not possible. | |
Public Attributes | |
| u32 | scalar_arg_count = 0xFFFF'FFFF |
| For vararg functions only: number of scalar and xmm registers used. | |
| u32 | max_callee_stack_arg_size |
| For functions without dynamic allocas, the largest size used for arguments passed on the stack to callees. | |
| bool | preserve_flags |
| Whether flags must be preserved when materializing constants etc. | |
| SymRef | sym_tls_get_addr |
| Symbol for __tls_get_addr. | |
Public Attributes inherited from tpde::CompilerBase< Adaptor, Derived, PlatformConfig > | |
| u32 | frame_size |
| The current size of the stack frame. | |
| bool | has_dynamic_alloca |
| Whether the stack frame might have dynamic alloca. | |
| bool | is_leaf_function |
| Whether the function is guaranteed to be a leaf function. | |
| bool | generated_call |
| Whether the function actually includes a call. | |
| bool | frame_used |
| Whether the stack frame is used. | |
| util::SmallVector< i32, 16 > | fixed_free_lists [5] |
| Free-Lists for 1/2/4/8/16 sized allocations. | |
| std::unordered_map< u32, std::vector< i32 > > | dynamic_free_lists |
| Free-Lists for all other sizes. | |
| bool | generating_branch |
| Whether we are currently in the middle of generating branch-related code and therefore must not change any value-related state. | |
Compiler mixin for targeting x86-64.
Definition at line 269 of file CompilerX64.hpp.
|
strong |
Jump conditions.
| Enumerator | |
|---|---|
| jo | Jump if overflow (OF=1). |
| jno | Jump if not overflow (OF=0). |
| jb | Jump if below/if carry (CF=1). |
| jae | Jump if above or equal/if not carry (CF=0). |
| je | Jump if equal/if zero (ZF=1). |
| jne | Jump if not equal/if not zero (ZF=0). |
| jbe | Jump if below or equal (CF=1 or ZF=1). |
| ja | Jump if above (CF=0 and ZF=0). |
| js | Jump if sign (SF=1). |
| jns | Jump if not sign (SF=0). |
| jp | Jump if parity even (PF=1). |
| jnp | Jump if parity odd (PF=0). |
| jl | Jump if less (SF!=OF). |
| jge | Jump if greater or equal (SF=OF). |
| jle | Jump if less or equal (ZF=1 or SF!=OF). |
| jg | Jump if greater (ZF=0 and SF=OF). |
| jmp | Unconditional jump. |
Definition at line 454 of file CompilerX64.hpp.
|
noexcept |
Dynamic alloca of a dynamically-sized region (elem_size * count bytes).
count must have a size of 64 bit.
Definition at line 1156 of file CompilerX64.hpp.
| void tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config >::generate_call | ( | std::variant< SymRef, ValuePart > && | target, |
| std::span< CallArg > | arguments, | ||
| typename Base::ValueRef * | result, | ||
| bool | variable_args = false ) |
Generate a function call.
This will get the arguments into the correct registers according to the calling convention, clear non-callee-saved registers from the register file (make sure you do not have any fixed assignments left over) and fill the result registers (the u8 in the ScratchReg pair indicates the register bank)
Targets can be a symbol (call to PLT with relocation), or an indirect call to a ValuePart. Result is an optional reference.
Definition at line 1796 of file CompilerX64.hpp.
|
noexcept |
Bitfield insert in zero.
src is not modified, but src and dst must be different.
Definition at line 1625 of file CompilerX64.hpp.
|
noexcept |
Integer extension.
Might need a temporary register, src is not modified, might clobber flags.
Definition at line 1524 of file CompilerX64.hpp.
|
noexcept |
Set dst to 1 if cc is true, otherwise set it to zero.
If zext is false, only the lowest 8 bit are set. Flags are not clobbered.
Definition at line 1489 of file CompilerX64.hpp.
|
noexcept |
Assign argument part.
Returns the stack offset if the value should be initialized as stack variable.
Definition at line 638 of file CompilerX64.hpp.
|
noexcept |
Generate code sequence to load address of sym into a register.
This will generate a function call for dynamic TLS access models.
Definition at line 1930 of file CompilerX64.hpp.
| u32 tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config >::max_callee_stack_arg_size |
For functions without dynamic allocas, the largest size used for arguments passed on the stack to callees.
This size is added to the stack pointer subtraction/addition in prologue/epilogue to avoid stack pointer adjustments at call sites.
Definition at line 345 of file CompilerX64.hpp.