Class: Rubycc::IR::SystemVAMD64Convention
- Inherits:
-
CallConvention
- Object
- CallConvention
- Rubycc::IR::SystemVAMD64Convention
- Defined in:
- lib/rubycc/ir/call_convention.rb
Overview
System V AMD64 (psABI 3.2.3).
Defined Under Namespace
Classes: Placer
Constant Summary
Constants inherited from CallConvention
CallConvention::AAPCS64, CallConvention::SYSTEM_V_AMD64
Instance Attribute Summary
Attributes inherited from CallConvention
#fp_registers, #gp_registers, #hidden_result_kind, #va_list_abi, #va_list_tag, #va_list_type
Instance Method Summary collapse
-
#aggregate_plan(type) ⇒ Object
Classifies an aggregate by the psABI's eightbyte rules.
-
#initialize ⇒ SystemVAMD64Convention
constructor
A new instance of SystemVAMD64Convention.
- #placer ⇒ Object
Methods inherited from CallConvention
Constructor Details
#initialize ⇒ SystemVAMD64Convention
Returns a new instance of SystemVAMD64Convention.
131 132 133 134 135 |
# File 'lib/rubycc/ir/call_convention.rb', line 131 def initialize super(gp_registers: 6, fp_registers: 8, va_list_tag: Type::VaListTag, va_list_type: Type::BuiltinVaList, va_list_abi: :system_v) end |
Instance Method Details
#aggregate_plan(type) ⇒ Object
Classifies an aggregate by the psABI's eightbyte rules. A struct or union larger than two eightbytes — or one with any unaligned field — is passed in memory; otherwise each of its one or two eightbytes gets a class from the scalar fields that fall in it, :gp for an INTEGER eightbyte and :sse8 for an SSE one (moved as a full 8-byte double even when it holds two packed floats, since a single movsd carries the whole eightbyte).
The unaligned-field test is what a GNU attribute((packed)) demands (Step 28): the psABI gives an aggregate "containing unaligned fields" class MEMORY, and gcc follows it — a packed struct whose field would straddle an eightbyte boundary is passed on the stack, not in registers. Every non-packed layout here is naturally aligned, so this only ever fires for a packed struct. (AAPCS64 has no such rule, which is one more reason the classification cannot be shared.)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/rubycc/ir/call_convention.rb', line 152 def aggregate_plan(type) size = type.size # A 16-byte-aligned aggregate (one holding an __int128, or _Alignas(16)) # is placed on a 16-byte-aligned stack slot when it spills, so its plan # carries the alignment for the placer to pad NSAA up to — even for a # MEMORY-class aggregate, whose stack slot the psABI aligns the same way. align16 = type.alignment >= 16 if size > 16 || unaligned_field?(type, 0) return AggregatePlan.new(mode: :memory, pieces: CallConvention.memory_pieces(size), align16: align16) end eightbytes = Array.new((size + 7) / 8, nil) classify_eightbytes(eightbytes, type, 0) # A NO_CLASS eightbyte (only padding fell in it) defaults to SSE, the # psABI's benign choice; INTEGER otherwise wins over SSE per #merge_class. pieces = eightbytes.each_with_index.map do |cls, i| AbiPiece.new(offset: 8 * i, size: 8, kind: cls == :integer ? :gp : :sse8) end AggregatePlan.new(mode: :registers, pieces: pieces, align16: align16) end |