HIR: Add opcode SET_ROUNDING_MODE (taking FPSCR as an argument)
This commit is contained in:
parent
dbece71945
commit
82efbd7bc5
|
@ -465,6 +465,7 @@ struct Sequence {
|
|||
const REG_CONST_FN& reg_const_fn) {
|
||||
if (i.src1.is_constant) {
|
||||
if (i.src2.is_constant) {
|
||||
// Both constants.
|
||||
if (i.src1.ConstantFitsIn32Reg()) {
|
||||
e.mov(i.dest, i.src2.constant());
|
||||
reg_const_fn(e, i.dest, static_cast<int32_t>(i.src1.constant()));
|
||||
|
@ -478,6 +479,7 @@ struct Sequence {
|
|||
reg_reg_fn(e, i.dest, temp);
|
||||
}
|
||||
} else {
|
||||
// src1 constant.
|
||||
if (i.dest == i.src2) {
|
||||
if (i.src1.ConstantFitsIn32Reg()) {
|
||||
reg_const_fn(e, i.dest, static_cast<int32_t>(i.src1.constant()));
|
||||
|
@ -7588,6 +7590,25 @@ struct ATOMIC_COMPARE_EXCHANGE_I64
|
|||
EMITTER_OPCODE_TABLE(OPCODE_ATOMIC_COMPARE_EXCHANGE,
|
||||
ATOMIC_COMPARE_EXCHANGE_I32, ATOMIC_COMPARE_EXCHANGE_I64);
|
||||
|
||||
// ============================================================================
|
||||
// OPCODE_SET_ROUNDING_MODE
|
||||
// ============================================================================
|
||||
// Input: FPSCR (PPC format)
|
||||
static const uint32_t mxcsr_table[] = {
|
||||
0x1F80, 0x7F80, 0x5F80, 0x3F80, 0x9F80, 0xFF80, 0xDF80, 0xBF80,
|
||||
};
|
||||
struct SET_ROUNDING_MODE_I32
|
||||
: Sequence<SET_ROUNDING_MODE_I32,
|
||||
I<OPCODE_SET_ROUNDING_MODE, VoidOp, I32Op>> {
|
||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||
e.mov(e.rcx, i.src1);
|
||||
e.and_(e.rcx, 0x7);
|
||||
e.mov(e.rax, uintptr_t(mxcsr_table));
|
||||
e.vldmxcsr(e.ptr[e.rax + e.rcx * 4]);
|
||||
}
|
||||
};
|
||||
EMITTER_OPCODE_TABLE(OPCODE_SET_ROUNDING_MODE, SET_ROUNDING_MODE_I32);
|
||||
|
||||
void RegisterSequences() {
|
||||
Register_OPCODE_COMMENT();
|
||||
Register_OPCODE_NOP();
|
||||
|
@ -7706,6 +7727,7 @@ void RegisterSequences() {
|
|||
Register_OPCODE_UNPACK();
|
||||
Register_OPCODE_ATOMIC_EXCHANGE();
|
||||
Register_OPCODE_ATOMIC_COMPARE_EXCHANGE();
|
||||
Register_OPCODE_SET_ROUNDING_MODE();
|
||||
}
|
||||
|
||||
bool SelectSequence(X64Emitter* e, const Instr* i, const Instr** new_tail) {
|
||||
|
|
|
@ -1269,6 +1269,12 @@ void HIRBuilder::Prefetch(Value* address, size_t length,
|
|||
|
||||
void HIRBuilder::MemoryBarrier() { AppendInstr(OPCODE_MEMORY_BARRIER_info, 0); }
|
||||
|
||||
void HIRBuilder::SetRoundingMode(Value* value) {
|
||||
ASSERT_INTEGER_TYPE(value);
|
||||
Instr* i = AppendInstr(OPCODE_SET_ROUNDING_MODE_info, 0);
|
||||
i->set_src1(value);
|
||||
}
|
||||
|
||||
Value* HIRBuilder::Max(Value* value1, Value* value2) {
|
||||
ASSERT_TYPES_EQUAL(value1, value2);
|
||||
|
||||
|
|
|
@ -153,6 +153,7 @@ class HIRBuilder {
|
|||
void Prefetch(Value* address, size_t length, uint32_t prefetch_flags = 0);
|
||||
void MemoryBarrier();
|
||||
|
||||
void SetRoundingMode(Value* value);
|
||||
Value* Max(Value* value1, Value* value2);
|
||||
Value* VectorMax(Value* value1, Value* value2, TypeName part_type,
|
||||
uint32_t arithmetic_flags = 0);
|
||||
|
|
|
@ -225,6 +225,7 @@ enum Opcode {
|
|||
OPCODE_UNPACK,
|
||||
OPCODE_ATOMIC_EXCHANGE,
|
||||
OPCODE_ATOMIC_COMPARE_EXCHANGE,
|
||||
OPCODE_SET_ROUNDING_MODE,
|
||||
__OPCODE_MAX_VALUE, // Keep at end.
|
||||
};
|
||||
|
||||
|
|
|
@ -649,3 +649,9 @@ DEFINE_OPCODE(
|
|||
"atomic_compare_exchange",
|
||||
OPCODE_SIG_V_V_V_V,
|
||||
OPCODE_FLAG_VOLATILE)
|
||||
|
||||
DEFINE_OPCODE(
|
||||
OPCODE_SET_ROUNDING_MODE,
|
||||
"set_rounding_mode",
|
||||
OPCODE_SIG_X_V,
|
||||
0)
|
||||
|
|
Loading…
Reference in New Issue