TPDE
Loading...
Searching...
No Matches
tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config > Struct Template Reference

Compiler mixin for targeting x86-64. More...

#include <CompilerX64.hpp>

Inheritance diagram for tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config >:
tpde::CompilerBase< Adaptor, Derived, PlatformConfig >

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.
 

Detailed Description

template<IRAdaptor Adaptor, typename Derived, template< typename, typename, typename > typename BaseTy = CompilerBase, typename Config = PlatformConfig>
struct tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config >

Compiler mixin for targeting x86-64.

Definition at line 269 of file CompilerX64.hpp.

Member Enumeration Documentation

◆ Jump

template<IRAdaptor Adaptor, typename Derived, template< typename, typename, typename > typename BaseTy = CompilerBase, typename Config = PlatformConfig>
enum class tpde::x64::CompilerX64::Jump
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.

Member Function Documentation

◆ alloca_dynamic()

template<IRAdaptor Adaptor, typename Derived, template< typename, typename, typename > typename BaseTy, typename Config>
void tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config >::alloca_dynamic ( u64 elem_size,
ValuePart && count,
u32 align,
ValuePart & res )
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.

◆ generate_call()

template<IRAdaptor Adaptor, typename Derived, template< typename, typename, typename > typename BaseTy, typename Config>
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.

◆ generate_raw_bfiz()

template<IRAdaptor Adaptor, typename Derived, template< typename, typename, typename > class BaseTy, typename Config>
void tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config >::generate_raw_bfiz ( AsmReg dst,
AsmReg src,
u32 lsb,
u32 width )
noexcept

Bitfield insert in zero.

src is not modified, but src and dst must be different.

Definition at line 1625 of file CompilerX64.hpp.

◆ generate_raw_intext()

template<IRAdaptor Adaptor, typename Derived, template< typename, typename, typename > class BaseTy, typename Config>
void tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config >::generate_raw_intext ( AsmReg dst,
AsmReg src,
bool sign,
u32 from,
u32 to )
noexcept

Integer extension.

Might need a temporary register, src is not modified, might clobber flags.

Definition at line 1524 of file CompilerX64.hpp.

◆ generate_raw_set()

template<IRAdaptor Adaptor, typename Derived, template< typename, typename, typename > class BaseTy, typename Config>
void tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config >::generate_raw_set ( Jump cc,
AsmReg dst,
bool zext = true )
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.

◆ prologue_assign_arg_part()

template<IRAdaptor Adaptor, typename Derived, template< typename, typename, typename > typename BaseTy, typename Config>
std::optional< i32 > tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config >::prologue_assign_arg_part ( ValuePart && vp,
CCAssignment cca )
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.

◆ tls_get_addr()

template<IRAdaptor Adaptor, typename Derived, template< typename, typename, typename > typename BaseTy, typename Config>
CompilerX64< Adaptor, Derived, BaseTy, Config >::ScratchReg tpde::x64::CompilerX64< Adaptor, Derived, BaseTy, Config >::tls_get_addr ( SymRef sym,
TLSModel model )
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.

Member Data Documentation

◆ max_callee_stack_arg_size

template<IRAdaptor Adaptor, typename Derived, template< typename, typename, typename > typename BaseTy = CompilerBase, typename Config = PlatformConfig>
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.


The documentation for this struct was generated from the following file: