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:
@@ -381,6 +381,7 @@ is zero.
|
|||||||
.. autoinst:: trapz
|
.. autoinst:: trapz
|
||||||
.. autoinst:: trapnz
|
.. autoinst:: trapnz
|
||||||
.. autoinst:: trapif
|
.. autoinst:: trapif
|
||||||
|
.. autoinst:: trapff
|
||||||
|
|
||||||
|
|
||||||
Function calls
|
Function calls
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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: }
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -366,6 +366,7 @@ impl<'a> Verifier<'a> {
|
|||||||
Trap { .. } |
|
Trap { .. } |
|
||||||
CondTrap { .. } |
|
CondTrap { .. } |
|
||||||
IntCondTrap { .. } |
|
IntCondTrap { .. } |
|
||||||
|
FloatCondTrap { .. } |
|
||||||
NullAry { .. } => {}
|
NullAry { .. } => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user