Fix up adjust_sp_imm instruction.

* Use imm64 rather than offset32
* Add predicate to enforce signed 32-bit limit to imm
* Remove AdjustSpImm format
* Add encoding tests for adjust_sp_imm
* Adjust use of adjust_sp_imm in Intel prologue_epilogue to match
This commit is contained in:
Tyler McMullen
2017-12-02 15:37:04 -08:00
committed by Jakob Stoklund Olesen
parent 1a11c351b5
commit ced39f5186
11 changed files with 46 additions and 27 deletions

View File

@@ -389,6 +389,17 @@ ebb0:
; asm: popl %ecx ; asm: popl %ecx
[-,%rcx] v512 = x86_pop.i32 ; bin: 59 [-,%rcx] v512 = x86_pop.i32 ; bin: 59
; Adjust Stack Pointer
; asm: addq $1024, %rsp
adjust_sp_imm 1024 ; bin: 81 c4 00000400
; asm: addq $-1024, %rsp
adjust_sp_imm -1024 ; bin: 81 c4 fffffc00
; asm: addq $2147483647, %rsp
adjust_sp_imm 2147483647 ; bin: 81 c4 7fffffff
; asm: addq $-2147483648, %rsp
adjust_sp_imm -2147483648 ; bin: 81 c4 80000000
; asm: testl %ecx, %ecx ; asm: testl %ecx, %ecx
; asm: je ebb1 ; asm: je ebb1
brz v1, ebb1 ; bin: 85 c9 74 0e brz v1, ebb1 ; bin: 85 c9 74 0e

View File

@@ -493,6 +493,16 @@ ebb0:
; asm: popq %r10 ; asm: popq %r10
[-,%r10] v514 = x86_pop.i64 ; bin: 41 5a [-,%r10] v514 = x86_pop.i64 ; bin: 41 5a
; Adjust Stack Pointer
; asm: addq $1024, %rsp
adjust_sp_imm 1024 ; bin: 48 81 c4 00000400
; asm: addq $-1024, %rsp
adjust_sp_imm -1024 ; bin: 48 81 c4 fffffc00
; asm: addq $2147483647, %rsp
adjust_sp_imm 2147483647 ; bin: 48 81 c4 7fffffff
; asm: addq $-2147483648, %rsp
adjust_sp_imm -2147483648 ; bin: 48 81 c4 80000000
; asm: testq %rcx, %rcx ; asm: testq %rcx, %rcx
; asm: je ebb1 ; asm: je ebb1
brz v1, ebb1 ; bin: 48 85 c9 74 1b brz v1, ebb1 ; bin: 48 85 c9 74 1b

View File

@@ -8,18 +8,18 @@ function %foo(f64 [%xmm0], i64 fp [%rbp], i64 csr [%rbx], i64 csr [%r12]) -> i64
ss1 = incoming_arg 32, offset -32 ss1 = incoming_arg 32, offset -32
ebb0(v0: f64 [%xmm0], v1: i64 [%rbp], v2: i64 [%rbx], v3: i64 [%r12]): ebb0(v0: f64 [%xmm0], v1: i64 [%rbp], v2: i64 [%rbx], v3: i64 [%r12]):
x86_push v1 ; bin: 48 55 x86_push v1 ; bin: 55
copy_special %rsp -> %rbp ; bin: 48 89 e5 copy_special %rsp -> %rbp ; bin: 48 89 e5
x86_push v2 ; bin: 48 53 x86_push v2 ; bin: 53
x86_push v3 ; bin: 49 54 x86_push v3 ; bin: 41 54
adjust_sp_imm -168 ; bin: 48 81 c4 ffffff58 adjust_sp_imm -168 ; bin: 48 81 c4 ffffff58
; ... function body ... ; ... function body ...
adjust_sp_imm +168 ; bin: 48 81 c4 000000a8 adjust_sp_imm 168 ; bin: 48 81 c4 000000a8
[-,%r12] v100 = x86_pop.i64 ; bin: 49 5c [-,%r12] v100 = x86_pop.i64 ; bin: 41 5c
[-,%rbx] v101 = x86_pop.i64 ; bin: 48 5b [-,%rbx] v101 = x86_pop.i64 ; bin: 5b
[-,%rbp] v102 = x86_pop.i64 ; bin: 48 5d [-,%rbp] v102 = x86_pop.i64 ; bin: 5d
return v100, v101, v102 return v100, v101, v102
} }

View File

@@ -69,7 +69,6 @@ RegSpill = InstructionFormat(
VALUE, ('src', regunit), ('dst', entities.stack_slot)) VALUE, ('src', regunit), ('dst', entities.stack_slot))
RegFill = InstructionFormat( RegFill = InstructionFormat(
VALUE, ('src', entities.stack_slot), ('dst', regunit)) VALUE, ('src', entities.stack_slot), ('dst', regunit))
AdjustSpImm = InstructionFormat(offset32)
Trap = InstructionFormat(trapcode) Trap = InstructionFormat(trapcode)
CondTrap = InstructionFormat(VALUE, trapcode) CondTrap = InstructionFormat(VALUE, trapcode)

View File

@@ -549,12 +549,16 @@ copy_special = Instruction(
ins=(src, dst), ins=(src, dst),
other_side_effects=True) other_side_effects=True)
Offset = Operand('Offset', offset32, 'Offset from current stack pointer') StackOffset = Operand('Offset', imm64, 'Offset from current stack pointer')
adjust_sp_imm = Instruction( adjust_sp_imm = Instruction(
'adjust_sp_imm', r""" 'adjust_sp_imm', r"""
Adds an immediate offset value to the stack pointer register. Adds ``Offset`` immediate offset value to the stack pointer register.
This instruction is used to adjust the stack pointer, primarily in function
prologues and epilogues. ``Offset`` is constrained to the size of a signed
32-bit integer.
""", """,
ins=(Offset,), ins=(StackOffset,),
other_side_effects=True) other_side_effects=True)
regspill = Instruction( regspill = Instruction(

View File

@@ -10,7 +10,7 @@ from base.formats import Trap, Call, IndirectCall, Store, Load
from base.formats import IntCompare, FloatCompare, IntCond, FloatCond from base.formats import IntCompare, FloatCompare, IntCond, FloatCond
from base.formats import Jump, Branch, BranchInt, BranchFloat from base.formats import Jump, Branch, BranchInt, BranchFloat
from base.formats import Ternary, FuncAddr, UnaryGlobalVar from base.formats import Ternary, FuncAddr, UnaryGlobalVar
from base.formats import RegMove, RegSpill, RegFill, CopySpecial, AdjustSpImm from base.formats import RegMove, RegSpill, RegFill, CopySpecial
from .registers import GPR, ABCD, FPR, GPR8, FPR8, FLAG, StackGPR32, StackFPR32 from .registers import GPR, ABCD, FPR, GPR8, FPR8, FLAG, StackGPR32, StackFPR32
from .defs import supported_floatccs from .defs import supported_floatccs
@@ -494,12 +494,13 @@ copysp = TailRecipe(
''') ''')
adjustsp = TailRecipe( adjustsp = TailRecipe(
'adjustsp', AdjustSpImm, size=5, ins=(), outs=(), 'adjustsp', UnaryImm, size=5, ins=(), outs=(),
instp=IsSignedInt(UnaryImm.imm, 32),
emit=''' emit='''
PUT_OP(bits, rex1(4), sink); PUT_OP(bits, rex1(4), sink);
modrm_r_bits(4, bits, sink); modrm_r_bits(4, bits, sink);
let offset: i32 = offset.into(); let imm: i64 = imm.into();
sink.put4(offset as u32); sink.put4(imm as u32);
''') ''')

View File

@@ -241,7 +241,6 @@ pub enum InstructionData {
src: RegUnit, src: RegUnit,
dst: RegUnit, dst: RegUnit,
}, },
AdjustSpImm { opcode: Opcode, offset: Offset32 },
RegSpill { RegSpill {
opcode: Opcode, opcode: Opcode,
arg: Value, arg: Value,

View File

@@ -16,6 +16,7 @@ use ir;
use regalloc; use regalloc;
use result; use result;
use ir::{InstBuilder, InstructionData, Opcode}; use ir::{InstBuilder, InstructionData, Opcode};
use ir::immediates::Imm64;
use stack_layout::layout_stack; use stack_layout::layout_stack;
use cursor::{Cursor, EncCursor}; use cursor::{Cursor, EncCursor};
@@ -141,7 +142,7 @@ impl TargetIsa for Isa {
func.create_stack_slot(slot); func.create_stack_slot(slot);
let total_stack_size = layout_stack(&mut func.stack_slots, word_size)?; let total_stack_size = layout_stack(&mut func.stack_slots, word_size)?;
let local_stack_size = total_stack_size - csr_stack_size; let local_stack_size = (total_stack_size - csr_stack_size) as i64;
// Build up list of args, which we'll append forwards to the params and // Build up list of args, which we'll append forwards to the params and
// backwards to the returns. // backwards to the returns.
@@ -203,7 +204,7 @@ impl TargetIsa for Isa {
RU::rbp as RegUnit, RU::rbp as RegUnit,
); );
if local_stack_size > 0 { if local_stack_size > 0 {
pos.ins().adjust_sp_imm(-(local_stack_size as i32)); pos.ins().adjust_sp_imm(Imm64::new(-local_stack_size));
} }
for csr_arg in csr_vals { for csr_arg in csr_vals {
@@ -226,7 +227,7 @@ impl TargetIsa for Isa {
// Insert an epilogue directly before every 'return' // Insert an epilogue directly before every 'return'
for inst in return_insts { for inst in return_insts {
self.insert_epilogue(inst, local_stack_size as i32, func, &csrs, csr_type); self.insert_epilogue(inst, local_stack_size, func, &csrs, csr_type);
} }
@@ -238,7 +239,7 @@ impl Isa {
fn insert_epilogue( fn insert_epilogue(
&self, &self,
inst: ir::Inst, inst: ir::Inst,
stack_size: i32, stack_size: i64,
func: &mut ir::Function, func: &mut ir::Function,
csrs: &Vec<RU>, csrs: &Vec<RU>,
csr_type: ir::types::Type, csr_type: ir::types::Type,
@@ -247,7 +248,7 @@ impl Isa {
let mut pos = EncCursor::new(func, self).at_inst(inst); let mut pos = EncCursor::new(func, self).at_inst(inst);
if stack_size > 0 { if stack_size > 0 {
pos.ins().adjust_sp_imm(stack_size); pos.ins().adjust_sp_imm(Imm64::new(stack_size));
} }
for reg in csrs.iter().rev() { for reg in csrs.iter().rev() {
let csr_ret = pos.ins().x86_pop(csr_type); let csr_ret = pos.ins().x86_pop(csr_type);

View File

@@ -359,7 +359,6 @@ impl<'a> Verifier<'a> {
Store { .. } | Store { .. } |
RegMove { .. } | RegMove { .. } |
CopySpecial { .. } | CopySpecial { .. } |
AdjustSpImm { .. } |
Trap { .. } | Trap { .. } |
CondTrap { .. } | CondTrap { .. } |
NullAry { .. } => {} NullAry { .. } => {}

View File

@@ -407,7 +407,6 @@ pub fn write_operands(
write!(w, " %{} -> %{}", src, dst) write!(w, " %{} -> %{}", src, dst)
} }
} }
AdjustSpImm { offset, .. } => write!(w, " {}", offset),
RegSpill { arg, src, dst, .. } => { RegSpill { arg, src, dst, .. } => {
if let Some(isa) = isa { if let Some(isa) = isa {
let regs = isa.register_info(); let regs = isa.register_info();

View File

@@ -2279,10 +2279,6 @@ impl<'a> Parser<'a> {
let dst = self.match_regunit(ctx.unique_isa)?; let dst = self.match_regunit(ctx.unique_isa)?;
InstructionData::CopySpecial { opcode, src, dst } InstructionData::CopySpecial { opcode, src, dst }
} }
InstructionFormat::AdjustSpImm => {
let offset = self.optional_offset32()?;
InstructionData::AdjustSpImm { opcode, offset }
}
InstructionFormat::RegSpill => { InstructionFormat::RegSpill => {
let arg = self.match_value("expected SSA value operand")?; let arg = self.match_value("expected SSA value operand")?;
self.match_token( self.match_token(