Add a trapff instruction.

This is the floating point equivalent of trapif: Trap when a given
condition is in the floating-point flags.

Define Intel encodings comparable to the trapif encodings.
This commit is contained in:
Jakob Stoklund Olesen
2018-02-20 14:35:41 -08:00
parent 1e56d44465
commit b9b1d0fcd5
12 changed files with 91 additions and 1 deletions

View File

@@ -381,6 +381,7 @@ is zero.
.. autoinst:: trapz .. autoinst:: trapz
.. autoinst:: trapnz .. autoinst:: trapnz
.. autoinst:: trapif .. autoinst:: trapif
.. autoinst:: trapff
Function calls Function calls

View File

@@ -470,6 +470,23 @@ ebb1:
; asm: jbe ebb1 ; asm: jbe ebb1
brff ule v1, ebb1 ; bin: 76 f0 brff ule v1, ebb1 ; bin: 76 f0
; asm: jp .+4; ud2
trapff ord v1, user0 ; bin: 7a 02 0f 0b
; asm: jnp .+4; ud2
trapff uno v1, user0 ; bin: 7b 02 0f 0b
; asm: je .+4; ud2
trapff one v1, user0 ; bin: 74 02 0f 0b
; asm: jne .+4; ud2
trapff ueq v1, user0 ; bin: 75 02 0f 0b
; asm: jna .+4; ud2
trapff gt v1, user0 ; bin: 76 02 0f 0b
; asm: jnae .+4; ud2
trapff ge v1, user0 ; bin: 72 02 0f 0b
; asm: jnb .+4; ud2
trapff ult v1, user0 ; bin: 73 02 0f 0b
; asm: jnbe .+4; ud2
trapff ule v1, user0 ; bin: 77 02 0f 0b
; asm: setnp %bl ; asm: setnp %bl
[-,%rbx] v10 = trueff ord v1 ; bin: 0f 9b c3 [-,%rbx] v10 = trueff ord v1 ; bin: 0f 9b c3
; asm: setp %bl ; asm: setp %bl

View File

@@ -494,6 +494,23 @@ ebb1:
; asm: jbe ebb1 ; asm: jbe ebb1
brff ule v1, ebb1 ; bin: 76 f0 brff ule v1, ebb1 ; bin: 76 f0
; asm: jp .+4; ud2
trapff ord v1, user0 ; bin: 7a 02 0f 0b
; asm: jnp .+4; ud2
trapff uno v1, user0 ; bin: 7b 02 0f 0b
; asm: je .+4; ud2
trapff one v1, user0 ; bin: 74 02 0f 0b
; asm: jne .+4; ud2
trapff ueq v1, user0 ; bin: 75 02 0f 0b
; asm: jna .+4; ud2
trapff gt v1, user0 ; bin: 76 02 0f 0b
; asm: jnae .+4; ud2
trapff ge v1, user0 ; bin: 72 02 0f 0b
; asm: jnb .+4; ud2
trapff ult v1, user0 ; bin: 73 02 0f 0b
; asm: jnbe .+4; ud2
trapff ule v1, user0 ; bin: 77 02 0f 0b
; asm: setnp %bl ; asm: setnp %bl
[-,%rbx] v10 = trueff ord v1 ; bin: 0f 9b c3 [-,%rbx] v10 = trueff ord v1 ; bin: 0f 9b c3
; asm: setp %bl ; asm: setp %bl

View File

@@ -216,6 +216,9 @@ ebb0(v0: i32):
trapz v0, stk_ovf trapz v0, stk_ovf
v1 = ifcmp_imm v0, 5 v1 = ifcmp_imm v0, 5
trapif ugt v1, oob trapif ugt v1, oob
v2 = bitcast.f32 v1
v3 = ffcmp v2, v2
trapff uno v3, int_ovf
return return
} }
; sameln: function %cond_traps(i32) ; sameln: function %cond_traps(i32)
@@ -223,5 +226,8 @@ ebb0(v0: i32):
; nextln: trapz $v0, stk_ovf ; nextln: trapz $v0, stk_ovf
; nextln: $v1 = ifcmp_imm v0, 5 ; nextln: $v1 = ifcmp_imm v0, 5
; nextln: trapif ugt $v1, oob ; nextln: trapif ugt $v1, oob
; nextln: $v2 = bitcast.f32 $v1
; nextln: $v3 = ffcmp $v2, $v2
; nextln: trapff uno $v3, int_ovf
; nextln: return ; nextln: return
; nextln: } ; nextln: }

View File

@@ -75,6 +75,7 @@ RegFill = InstructionFormat(
Trap = InstructionFormat(trapcode) Trap = InstructionFormat(trapcode)
CondTrap = InstructionFormat(VALUE, trapcode) CondTrap = InstructionFormat(VALUE, trapcode)
IntCondTrap = InstructionFormat(intcc, VALUE, trapcode) IntCondTrap = InstructionFormat(intcc, VALUE, trapcode)
FloatCondTrap = InstructionFormat(floatcc, VALUE, trapcode)
# Finally extract the names of global variables in this module. # Finally extract the names of global variables in this module.
InstructionFormat.extract_names(globals()) InstructionFormat.extract_names(globals())

View File

@@ -176,6 +176,15 @@ trapif = Instruction(
""", """,
ins=(Cond, f, code), can_trap=True) ins=(Cond, f, code), can_trap=True)
Cond = Operand('Cond', floatcc)
f = Operand('f', fflags)
trapff = Instruction(
'trapff', r"""
Trap when condition is true in floating point CPU flags.
""",
ins=(Cond, f, code), can_trap=True)
rvals = Operand('rvals', VARIABLE_ARGS, doc='return values') rvals = Operand('rvals', VARIABLE_ARGS, doc='return values')
x_return = Instruction( x_return = Instruction(

View File

@@ -357,6 +357,8 @@ I64.enc(base.trap, *r.trap(0x0f, 0x0b))
# Using a standard EncRecipe, not the TailRecipe. # Using a standard EncRecipe, not the TailRecipe.
I32.enc(base.trapif, r.trapif, 0) I32.enc(base.trapif, r.trapif, 0)
I64.enc(base.trapif, r.trapif, 0) I64.enc(base.trapif, r.trapif, 0)
I32.enc(base.trapff, r.trapff, 0)
I64.enc(base.trapff, r.trapff, 0)
# #
# Comparisons # Comparisons

View File

@@ -8,7 +8,7 @@ from cdsl.registers import RegClass
from base.formats import Unary, UnaryImm, Binary, BinaryImm, MultiAry, NullAry from base.formats import Unary, UnaryImm, Binary, BinaryImm, MultiAry, NullAry
from base.formats import Trap, Call, IndirectCall, Store, Load 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 IntSelect, IntCondTrap from base.formats import IntSelect, IntCondTrap, FloatCondTrap
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 from base.formats import RegMove, RegSpill, RegFill, CopySpecial
@@ -292,6 +292,20 @@ trapif = EncRecipe(
sink.put1(0x0b); sink.put1(0x0b);
''') ''')
trapff = EncRecipe(
'trapff', FloatCondTrap, size=4, ins=FLAG.eflags, outs=(),
clobbers_flags=False,
instp=floatccs(FloatCondTrap),
emit='''
// Jump over a 2-byte ud2.
sink.put1(0x70 | (fcc2opc(cond.inverse()) as u8));
sink.put1(2);
// ud2.
sink.put1(0x0f);
sink.put1(0x0b);
''')
# XX /r # XX /r
rr = TailRecipe( rr = TailRecipe(
'rr', Binary, size=1, ins=(GPR, GPR), outs=0, 'rr', Binary, size=1, ins=(GPR, GPR), outs=0,

View File

@@ -270,6 +270,12 @@ pub enum InstructionData {
arg: Value, arg: Value,
code: ir::TrapCode, code: ir::TrapCode,
}, },
FloatCondTrap {
opcode: Opcode,
cond: FloatCC,
arg: Value,
code: ir::TrapCode,
},
} }
/// A variable list of `Value` operands used for function call arguments and passing arguments to /// A variable list of `Value` operands used for function call arguments and passing arguments to

View File

@@ -366,6 +366,7 @@ impl<'a> Verifier<'a> {
Trap { .. } | Trap { .. } |
CondTrap { .. } | CondTrap { .. } |
IntCondTrap { .. } | IntCondTrap { .. } |
FloatCondTrap { .. } |
NullAry { .. } => {} NullAry { .. } => {}
} }

View File

@@ -429,6 +429,7 @@ pub fn write_operands(
Trap { code, .. } => write!(w, " {}", code), Trap { code, .. } => write!(w, " {}", code),
CondTrap { arg, code, .. } => write!(w, " {}, {}", arg, code), CondTrap { arg, code, .. } => write!(w, " {}, {}", arg, code),
IntCondTrap { cond, arg, code, .. } => write!(w, " {} {}, {}", cond, arg, code), IntCondTrap { cond, arg, code, .. } => write!(w, " {} {}, {}", cond, arg, code),
FloatCondTrap { cond, arg, code, .. } => write!(w, " {} {}, {}", cond, arg, code),
} }
} }

View File

@@ -2363,6 +2363,21 @@ impl<'a> Parser<'a> {
code, code,
} }
} }
InstructionFormat::FloatCondTrap => {
let cond = self.match_enum("expected floatcc condition code")?;
let arg = self.match_value("expected SSA value operand")?;
self.match_token(
Token::Comma,
"expected ',' between operands",
)?;
let code = self.match_enum("expected trap code")?;
InstructionData::FloatCondTrap {
opcode,
cond,
arg,
code,
}
}
}; };
Ok(idata) Ok(idata)
} }