Class: Rubycc::IR::SystemVAMD64Convention::Placer

Inherits:
Object
  • Object
show all
Defined in:
lib/rubycc/ir/call_convention.rb

Overview

Hands out the integer and SSE registers over one argument list. Each argument is placed as a unit: its required registers of both files are counted first, and only if both fit in what remains does it take them; otherwise the whole argument spills and no register is consumed — the psABI rule that an argument whose parts do not all fit in registers passes wholly in memory, and the reason a later, smaller argument can still be handed a register the spilled one could not use.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(convention) ⇒ Placer

Returns a new instance of Placer.



261
262
263
264
265
266
267
# File 'lib/rubycc/ir/call_convention.rb', line 261

def initialize(convention)
  @convention = convention
  @next_gp = 0
  @next_sse = 0
  @nsaa = 0        # next stacked argument, counted in eightbytes
  @pad_stack = 0
end

Instance Attribute Details

#pad_stackObject (readonly)

One stack eightbyte the most recent #place reserved to 16-align a spilled 16-byte-aligned argument (the psABI aligns a stacked argument to its natural alignment, so an __int128 that overflowed the registers onto an odd stack offset starts a slot later). Zero otherwise.



280
281
282
# File 'lib/rubycc/ir/call_convention.rb', line 280

def pad_stack
  @pad_stack
end

Instance Method Details

#pad_gpObject

System V has no even-register-pair rule — a 16-byte argument takes two consecutive integer registers of either parity — so #place never reserves a padding register.



272
273
274
# File 'lib/rubycc/ir/call_convention.rb', line 272

def pad_gp
  0
end

#place(request) ⇒ Object

:registers when the argument takes the registers its request asks for, :stack when it passes in the overflow area. A request that is already all-:mem (a MEMORY-classified aggregate) never wanted a register.



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/rubycc/ir/call_convention.rb', line 285

def place(request)
  @pad_stack = 0
  need_gp = request.kinds.count(:gp)
  need_sse = request.kinds.count { |kind| kind == :sse4 || kind == :sse8 }
  spills = request.kinds.all?(:mem) ||
           !(@next_gp + need_gp <= @convention.gp_registers &&
             @next_sse + need_sse <= @convention.fp_registers)
  if spills
    @pad_stack = 1 if request.align16 && @nsaa.odd?
    @nsaa += @pad_stack + request.mem_eightbytes
    return :stack
  end

  @next_gp += need_gp
  @next_sse += need_sse
  :registers
end