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:
committed by
Jakob Stoklund Olesen
parent
1a11c351b5
commit
ced39f5186
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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);
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -359,7 +359,6 @@ impl<'a> Verifier<'a> {
|
|||||||
Store { .. } |
|
Store { .. } |
|
||||||
RegMove { .. } |
|
RegMove { .. } |
|
||||||
CopySpecial { .. } |
|
CopySpecial { .. } |
|
||||||
AdjustSpImm { .. } |
|
|
||||||
Trap { .. } |
|
Trap { .. } |
|
||||||
CondTrap { .. } |
|
CondTrap { .. } |
|
||||||
NullAry { .. } => {}
|
NullAry { .. } => {}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user