Commit d5f0178a authored by andrew-cc-chen's avatar andrew-cc-chen Committed by Commit Bot

[s390] added SIMD assembler and simulator instructions

Change-Id: I2bc21a353c871652daeac87eae62e1e6ae740b49
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1529638Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#60955}
parent 49954eb5
...@@ -48,6 +48,7 @@ enum CpuFeature { ...@@ -48,6 +48,7 @@ enum CpuFeature {
GENERAL_INSTR_EXT, GENERAL_INSTR_EXT,
FLOATING_POINT_EXT, FLOATING_POINT_EXT,
VECTOR_FACILITY, VECTOR_FACILITY,
VECTOR_ENHANCE_FACILITY_1,
MISC_INSTR_EXT2, MISC_INSTR_EXT2,
NUMBER_OF_CPU_FEATURES, NUMBER_OF_CPU_FEATURES,
......
...@@ -210,6 +210,11 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { ...@@ -210,6 +210,11 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
supportsCPUFeature("vx")) { supportsCPUFeature("vx")) {
supported_ |= (1u << VECTOR_FACILITY); supported_ |= (1u << VECTOR_FACILITY);
} }
// Test for Vector Enhancement Facility 1 - Bit 135
if (facilities[2] & (one << (63 - (135 - 128))) &&
supportsCPUFeature("vx")) {
supported_ |= (1u << VECTOR_ENHANCE_FACILITY_1);
}
// Test for Miscellaneous Instruction Extension Facility - Bit 58 // Test for Miscellaneous Instruction Extension Facility - Bit 58
if (facilities[0] & (1lu << (63 - 58))) { if (facilities[0] & (1lu << (63 - 58))) {
supported_ |= (1u << MISC_INSTR_EXT2); supported_ |= (1u << MISC_INSTR_EXT2);
...@@ -225,6 +230,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { ...@@ -225,6 +230,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
USE(performSTFLE); // To avoid assert USE(performSTFLE); // To avoid assert
USE(supportsCPUFeature); USE(supportsCPUFeature);
supported_ |= (1u << VECTOR_FACILITY); supported_ |= (1u << VECTOR_FACILITY);
supported_ |= (1u << VECTOR_ENHANCE_FACILITY_1);
#endif #endif
supported_ |= (1u << FPU); supported_ |= (1u << FPU);
} }
......
...@@ -1151,6 +1151,7 @@ inline void ss_a_format(Opcode op, int f1, int f2, int f3, int f4, int f5) { ...@@ -1151,6 +1151,7 @@ inline void ss_a_format(Opcode op, int f1, int f2, int f3, int f4, int f5) {
(static_cast<uint64_t>(m5 & 0xF)) * B20 | \ (static_cast<uint64_t>(m5 & 0xF)) * B20 | \
(static_cast<uint64_t>(m4 & 0xF)) * B16 | \ (static_cast<uint64_t>(m4 & 0xF)) * B16 | \
(static_cast<uint64_t>(m3 & 0xF)) * B12 | \ (static_cast<uint64_t>(m3 & 0xF)) * B12 | \
(static_cast<uint64_t>(0)) * B8 | \
(static_cast<uint64_t>(opcode_value & 0x00FF)); \ (static_cast<uint64_t>(opcode_value & 0x00FF)); \
emit6bytes(code); \ emit6bytes(code); \
} }
...@@ -1167,12 +1168,141 @@ inline void ss_a_format(Opcode op, int f1, int f2, int f3, int f4, int f5) { ...@@ -1167,12 +1168,141 @@ inline void ss_a_format(Opcode op, int f1, int f2, int f3, int f4, int f5) {
(static_cast<uint64_t>(m6 & 0xF)) * B20 | \ (static_cast<uint64_t>(m6 & 0xF)) * B20 | \
(static_cast<uint64_t>(m5 & 0xF)) * B16 | \ (static_cast<uint64_t>(m5 & 0xF)) * B16 | \
(static_cast<uint64_t>(m4 & 0xF)) * B12 | \ (static_cast<uint64_t>(m4 & 0xF)) * B12 | \
(static_cast<uint64_t>(0)) * B8 | \
(static_cast<uint64_t>(opcode_value & 0x00FF)); \ (static_cast<uint64_t>(opcode_value & 0x00FF)); \
emit6bytes(code); \ emit6bytes(code); \
} }
S390_VRR_C_OPCODE_LIST(DECLARE_VRR_C_INSTRUCTIONS) S390_VRR_C_OPCODE_LIST(DECLARE_VRR_C_INSTRUCTIONS)
#undef DECLARE_VRR_C_INSTRUCTIONS #undef DECLARE_VRR_C_INSTRUCTIONS
#define DECLARE_VRR_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
void name(DoubleRegister v1, DoubleRegister v2, DoubleRegister v3, \
Condition m5, Condition m4) { \
uint64_t code = (static_cast<uint64_t>(opcode_value & 0xFF00)) * B32 | \
(static_cast<uint64_t>(v1.code())) * B36 | \
(static_cast<uint64_t>(v2.code())) * B32 | \
(static_cast<uint64_t>(v3.code())) * B28 | \
(static_cast<uint64_t>(m5 & 0xF)) * B20 | \
(static_cast<uint64_t>(m4 & 0xF)) * B12 | \
(static_cast<uint64_t>(0)) * B8 | \
(static_cast<uint64_t>(opcode_value & 0x00FF)); \
emit6bytes(code); \
}
S390_VRR_B_OPCODE_LIST(DECLARE_VRR_B_INSTRUCTIONS)
#undef DECLARE_VRR_B_INSTRUCTIONS
#define DECLARE_VRR_E_INSTRUCTIONS(name, opcode_name, opcode_value) \
void name(DoubleRegister v1, DoubleRegister v2, DoubleRegister v3, \
DoubleRegister v4, Condition m6, Condition m5) { \
uint64_t code = (static_cast<uint64_t>(opcode_value & 0xFF00)) * B32 | \
(static_cast<uint64_t>(v1.code())) * B36 | \
(static_cast<uint64_t>(v2.code())) * B32 | \
(static_cast<uint64_t>(v3.code())) * B28 | \
(static_cast<uint64_t>(m6 & 0xF)) * B24 | \
(static_cast<uint64_t>(m5 & 0xF)) * B16 | \
(static_cast<uint64_t>(v4.code())) * B12 | \
(static_cast<uint64_t>(0)) * B8 | \
(static_cast<uint64_t>(opcode_value & 0x00FF)); \
emit6bytes(code); \
}
S390_VRR_E_OPCODE_LIST(DECLARE_VRR_E_INSTRUCTIONS)
#undef DECLARE_VRR_E_INSTRUCTIONS
#define DECLARE_VRX_INSTRUCTIONS(name, opcode_name, opcode_value) \
void name(DoubleRegister v1, const MemOperand& opnd, Condition m3) { \
uint64_t code = \
(static_cast<uint64_t>(opcode_value & 0xFF00)) * B32 | \
(static_cast<uint64_t>(v1.code())) * B36 | \
(static_cast<uint64_t>(opnd.getIndexRegister().code())) * B32 | \
(static_cast<uint64_t>(opnd.getBaseRegister().code())) * B28 | \
(static_cast<uint64_t>(opnd.getDisplacement())) * B16 | \
(static_cast<uint64_t>(m3 & 0xF)) * B12 | \
(static_cast<uint64_t>(0)) * B8 | \
(static_cast<uint64_t>(opcode_value & 0x00FF)); \
emit6bytes(code); \
}
S390_VRX_OPCODE_LIST(DECLARE_VRX_INSTRUCTIONS)
#undef DECLARE_VRX_INSTRUCTIONS
#define DECLARE_VRS_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
void name(DoubleRegister v1, DoubleRegister v2, const MemOperand& opnd, \
Condition m4 = Condition(0)) { \
uint64_t code = \
(static_cast<uint64_t>(opcode_value & 0xFF00)) * B32 | \
(static_cast<uint64_t>(v1.code())) * B36 | \
(static_cast<uint64_t>(v2.code())) * B32 | \
(static_cast<uint64_t>(opnd.getBaseRegister().code())) * B28 | \
(static_cast<uint64_t>(opnd.getDisplacement())) * B16 | \
(static_cast<uint64_t>(m4 & 0xF)) * B12 | \
(static_cast<uint64_t>(0)) * B8 | \
(static_cast<uint64_t>(opcode_value & 0x00FF)); \
emit6bytes(code); \
}
S390_VRS_A_OPCODE_LIST(DECLARE_VRS_A_INSTRUCTIONS)
#undef DECLARE_VRS_A_INSTRUCTIONS
#define DECLARE_VRS_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
void name(DoubleRegister v1, Register r1, const MemOperand& opnd, \
Condition m4 = Condition(0)) { \
uint64_t code = \
(static_cast<uint64_t>(opcode_value & 0xFF00)) * B32 | \
(static_cast<uint64_t>(v1.code())) * B36 | \
(static_cast<uint64_t>(r1.code())) * B32 | \
(static_cast<uint64_t>(opnd.getBaseRegister().code())) * B28 | \
(static_cast<uint64_t>(opnd.getDisplacement())) * B16 | \
(static_cast<uint64_t>(m4 & 0xF)) * B12 | \
(static_cast<uint64_t>(0)) * B8 | \
(static_cast<uint64_t>(opcode_value & 0x00FF)); \
emit6bytes(code); \
}
S390_VRS_B_OPCODE_LIST(DECLARE_VRS_B_INSTRUCTIONS)
#undef DECLARE_VRS_B_INSTRUCTIONS
#define DECLARE_VRS_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
void name(Register r1, DoubleRegister v1, const MemOperand& opnd, \
Condition m4 = Condition(0)) { \
uint64_t code = \
(static_cast<uint64_t>(opcode_value & 0xFF00)) * B32 | \
(static_cast<uint64_t>(r1.code())) * B36 | \
(static_cast<uint64_t>(v1.code())) * B32 | \
(static_cast<uint64_t>(opnd.getBaseRegister().code())) * B28 | \
(static_cast<uint64_t>(opnd.getDisplacement())) * B16 | \
(static_cast<uint64_t>(m4 & 0xF)) * B12 | \
(static_cast<uint64_t>(0)) * B8 | \
(static_cast<uint64_t>(opcode_value & 0x00FF)); \
emit6bytes(code); \
}
S390_VRS_C_OPCODE_LIST(DECLARE_VRS_C_INSTRUCTIONS)
#undef DECLARE_VRS_C_INSTRUCTIONS
#define DECLARE_VRI_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
void name(DoubleRegister v1, const Operand& i2, Condition m3) { \
uint64_t code = (static_cast<uint64_t>(opcode_value & 0xFF00)) * B32 | \
(static_cast<uint64_t>(v1.code())) * B36 | \
(static_cast<uint32_t>(i2.immediate())) * B16 | \
(static_cast<uint64_t>(m3 & 0xF)) * B12 | \
(static_cast<uint64_t>(0)) * B8 | \
(static_cast<uint64_t>(opcode_value & 0x00FF)); \
emit6bytes(code); \
}
S390_VRI_A_OPCODE_LIST(DECLARE_VRI_A_INSTRUCTIONS)
#undef DECLARE_VRI_A_INSTRUCTIONS
#define DECLARE_VRI_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
void name(DoubleRegister v1, DoubleRegister v2, const Operand& i2, \
Condition m4) { \
uint64_t code = (static_cast<uint64_t>(opcode_value & 0xFF00)) * B32 | \
(static_cast<uint64_t>(v1.code())) * B36 | \
(static_cast<uint64_t>(v2.code())) * B32 | \
(static_cast<uint16_t>(i2.immediate())) * B16 | \
(static_cast<uint64_t>(m4 & 0xF)) * B12 | \
(static_cast<uint64_t>(0)) * B8 | \
(static_cast<uint64_t>(opcode_value & 0x00FF)); \
emit6bytes(code); \
}
S390_VRI_C_OPCODE_LIST(DECLARE_VRI_C_INSTRUCTIONS)
#undef DECLARE_VRI_C_INSTRUCTIONS
// Single Element format // Single Element format
void vfa(DoubleRegister v1, DoubleRegister v2, DoubleRegister v3) { void vfa(DoubleRegister v1, DoubleRegister v2, DoubleRegister v3) {
vfa(v1, v2, v3, static_cast<Condition>(0), static_cast<Condition>(8), vfa(v1, v2, v3, static_cast<Condition>(0), static_cast<Condition>(8),
......
...@@ -559,6 +559,8 @@ typedef uint64_t SixByteInstr; ...@@ -559,6 +559,8 @@ typedef uint64_t SixByteInstr;
V(vfce, VFCE, 0xE7E8) /* type = VRR_C VECTOR FP COMPARE EQUAL */ \ V(vfce, VFCE, 0xE7E8) /* type = VRR_C VECTOR FP COMPARE EQUAL */ \
V(vfche, VFCHE, 0xE7EA) /* type = VRR_C VECTOR FP COMPARE HIGH OR EQUAL */ \ V(vfche, VFCHE, 0xE7EA) /* type = VRR_C VECTOR FP COMPARE HIGH OR EQUAL */ \
V(vfch, VFCH, 0xE7EB) /* type = VRR_C VECTOR FP COMPARE HIGH */ \ V(vfch, VFCH, 0xE7EB) /* type = VRR_C VECTOR FP COMPARE HIGH */ \
V(vfmax, VFMAX, 0xE7EF) /* type = VRR_C VECTOR FP MAXIMUM */ \
V(vfmin, VFMIN, 0xE7EE) /* type = VRR_C VECTOR FP MINIMUM */ \
V(vavgl, VAVGL, 0xE7F0) /* type = VRR_C VECTOR AVERAGE LOGICAL */ \ V(vavgl, VAVGL, 0xE7F0) /* type = VRR_C VECTOR AVERAGE LOGICAL */ \
V(vacc, VACC, 0xE7F1) /* type = VRR_C VECTOR ADD COMPUTE CARRY */ \ V(vacc, VACC, 0xE7F1) /* type = VRR_C VECTOR ADD COMPUTE CARRY */ \
V(vavg, VAVG, 0xE7F2) /* type = VRR_C VECTOR AVERAGE */ \ V(vavg, VAVG, 0xE7F2) /* type = VRR_C VECTOR AVERAGE */ \
...@@ -2288,6 +2290,24 @@ class RIEInstruction : Instruction { ...@@ -2288,6 +2290,24 @@ class RIEInstruction : Instruction {
}; };
// VRR Instruction // VRR Instruction
class VRR_A_Instruction : SixByteInstruction {
public:
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R1Value, int, 8, 12)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R2Value, int, 12, 16)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M5Value, uint32_t, 24, 28)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M4Value, uint32_t, 28, 32)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M3Value, uint32_t, 32, 36)
};
class VRR_B_Instruction : SixByteInstruction {
public:
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R1Value, int, 8, 12)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R2Value, int, 12, 16)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R3Value, int, 16, 20)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M5Value, uint32_t, 24, 28)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M4Value, uint32_t, 32, 36)
};
class VRR_C_Instruction : SixByteInstruction { class VRR_C_Instruction : SixByteInstruction {
public: public:
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R1Value, int, 8, 12) DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R1Value, int, 8, 12)
...@@ -2298,6 +2318,49 @@ class VRR_C_Instruction : SixByteInstruction { ...@@ -2298,6 +2318,49 @@ class VRR_C_Instruction : SixByteInstruction {
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M4Value, uint32_t, 32, 36) DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M4Value, uint32_t, 32, 36)
}; };
class VRR_E_Instruction : SixByteInstruction {
public:
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R1Value, int, 8, 12)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R2Value, int, 12, 16)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R3Value, int, 16, 20)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R4Value, int, 32, 36)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M6Value, uint32_t, 20, 24)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M5Value, uint32_t, 28, 32)
};
class VRX_Instruction : SixByteInstruction {
public:
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R1Value, int, 8, 12)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(X2Value, int, 12, 16)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(B2Value, int, 16, 20)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(D2Value, int, 20, 32)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M3Value, uint32_t, 32, 36)
};
class VRS_Instruction : SixByteInstruction {
public:
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R1Value, int, 8, 12)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R3Value, int, 12, 16)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(B2Value, int, 16, 20)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(D2Value, int, 20, 32)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M4Value, uint32_t, 32, 36)
};
class VRI_A_Instruction : SixByteInstruction {
public:
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R1Value, int, 8, 12)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(I2Value, int, 16, 32)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M3Value, uint32_t, 32, 36)
};
class VRI_C_Instruction : SixByteInstruction {
public:
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R1Value, int, 8, 12)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(R3Value, int, 12, 16)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(I2Value, int, 16, 32)
DECLARE_FIELD_FOR_SIX_BYTE_INSTR(M4Value, uint32_t, 32, 36)
};
// Helper functions for converting between register numbers and names. // Helper functions for converting between register numbers and names.
class Registers { class Registers {
public: public:
......
...@@ -210,6 +210,11 @@ int Decoder::FormatFloatingRegister(Instruction* instr, const char* format) { ...@@ -210,6 +210,11 @@ int Decoder::FormatFloatingRegister(Instruction* instr, const char* format) {
int reg = rreinstr->R2Value(); int reg = rreinstr->R2Value();
PrintDRegister(reg); PrintDRegister(reg);
return 2; return 2;
} else if (format[1] == '4') {
VRR_E_Instruction* vrreinstr = reinterpret_cast<VRR_E_Instruction*>(instr);
int reg = vrreinstr->R4Value();
PrintDRegister(reg);
return 2;
} }
UNREACHABLE(); UNREACHABLE();
} }
...@@ -311,8 +316,19 @@ int Decoder::FormatMask(Instruction* instr, const char* format) { ...@@ -311,8 +316,19 @@ int Decoder::FormatMask(Instruction* instr, const char* format) {
value = reinterpret_cast<RRFInstruction*>(instr)->M4Value(); value = reinterpret_cast<RRFInstruction*>(instr)->M4Value();
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value); out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
return 2; return 2;
} else if (format[1] == '4') { // mask format in bits 32-35
value = reinterpret_cast<VRR_C_Instruction*>(instr)->M4Value();
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
return 2;
} else if (format[1] == '5') { // mask format in bits 28-31
value = reinterpret_cast<VRR_C_Instruction*>(instr)->M5Value();
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
return 2;
} else if (format[1] == '6') { // mask format in bits 24-27
value = reinterpret_cast<VRR_C_Instruction*>(instr)->M6Value();
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
return 2;
} }
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
return 2; return 2;
} }
...@@ -784,13 +800,76 @@ bool Decoder::DecodeGeneric(Instruction* instr) { ...@@ -784,13 +800,76 @@ bool Decoder::DecodeGeneric(Instruction* instr) {
#undef DECODE_SI_INSTRUCTIONS #undef DECODE_SI_INSTRUCTIONS
/* 6 bytes */ /* 6 bytes */
#define DECODE_VRR_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'f2,'m4,'m5,'m6"); \
break;
S390_VRR_A_OPCODE_LIST(DECODE_VRR_A_INSTRUCTIONS)
#undef DECODE_VRR_A_INSTRUCTIONS
#define DECODE_VRR_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'f2,'f3,'m4,'m6"); \
break;
S390_VRR_B_OPCODE_LIST(DECODE_VRR_B_INSTRUCTIONS)
#undef DECODE_VRR_B_INSTRUCTIONS
#define DECODE_VRR_C_INSTRUCTIONS(name, opcode_name, opcode_value) \ #define DECODE_VRR_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \ case opcode_name: \
Format(instr, #name "\t'f1,'f2,'f3"); \ Format(instr, #name "\t'f1,'f2,'f3,'m4"); \
break; break;
S390_VRR_C_OPCODE_LIST(DECODE_VRR_C_INSTRUCTIONS) S390_VRR_C_OPCODE_LIST(DECODE_VRR_C_INSTRUCTIONS)
#undef DECODE_VRR_C_INSTRUCTIONS #undef DECODE_VRR_C_INSTRUCTIONS
#define DECODE_VRR_E_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'f2,'f3,'f4,'m5,'m3"); \
break;
S390_VRR_E_OPCODE_LIST(DECODE_VRR_E_INSTRUCTIONS)
#undef DECODE_VRR_E_INSTRUCTIONS
#define DECODE_VRX_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'d1('r2d,'r3),'m4"); \
break;
S390_VRX_OPCODE_LIST(DECODE_VRX_INSTRUCTIONS)
#undef DECODE_VRX_INSTRUCTIONS
#define DECODE_VRS_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'f2,'d1('r3),'m4"); \
break;
S390_VRS_A_OPCODE_LIST(DECODE_VRS_A_INSTRUCTIONS)
#undef DECODE_VRS_A_INSTRUCTIONS
#define DECODE_VRS_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'r2,'d1('r3),'m4"); \
break;
S390_VRS_B_OPCODE_LIST(DECODE_VRS_B_INSTRUCTIONS)
#undef DECODE_VRS_B_INSTRUCTIONS
#define DECODE_VRS_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'f2,'d1('r3),'m4"); \
break;
S390_VRS_C_OPCODE_LIST(DECODE_VRS_C_INSTRUCTIONS)
#undef DECODE_VRS_C_INSTRUCTIONS
#define DECODE_VRI_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'i1,'m4"); \
break;
S390_VRI_A_OPCODE_LIST(DECODE_VRI_A_INSTRUCTIONS)
#undef DECODE_VRI_A_INSTRUCTIONS
#define DECODE_VRI_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'f2,'i1,'m4"); \
break;
S390_VRI_C_OPCODE_LIST(DECODE_VRI_C_INSTRUCTIONS)
#undef DECODE_VRI_C_INSTRUCTIONS
#define DECODE_RIL_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ #define DECODE_RIL_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \ case opcode_name: \
Format(instr, #name "\t'r1,'i7"); \ Format(instr, #name "\t'r1,'i7"); \
......
...@@ -3864,6 +3864,11 @@ void TurboAssembler::LoadFloat32ConvertToDouble(DoubleRegister dst, ...@@ -3864,6 +3864,11 @@ void TurboAssembler::LoadFloat32ConvertToDouble(DoubleRegister dst,
ldebr(dst, dst); ldebr(dst, dst);
} }
void TurboAssembler::LoadSimd128(Simd128Register dst, const MemOperand& mem) {
DCHECK(is_uint12(mem.offset()));
vl(dst, mem, Condition(0));
}
// Store Double Precision (64-bit) Floating Point number to memory // Store Double Precision (64-bit) Floating Point number to memory
void TurboAssembler::StoreDouble(DoubleRegister dst, const MemOperand& mem) { void TurboAssembler::StoreDouble(DoubleRegister dst, const MemOperand& mem) {
if (is_uint12(mem.offset())) { if (is_uint12(mem.offset())) {
...@@ -3891,6 +3896,11 @@ void TurboAssembler::StoreDoubleAsFloat32(DoubleRegister src, ...@@ -3891,6 +3896,11 @@ void TurboAssembler::StoreDoubleAsFloat32(DoubleRegister src,
StoreFloat32(scratch, mem); StoreFloat32(scratch, mem);
} }
void TurboAssembler::StoreSimd128(Simd128Register src, const MemOperand& mem) {
DCHECK(is_uint12(mem.offset()));
vst(src, mem, Condition(0));
}
void TurboAssembler::AddFloat32(DoubleRegister dst, const MemOperand& opnd, void TurboAssembler::AddFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch) { DoubleRegister scratch) {
if (is_uint12(opnd.offset())) { if (is_uint12(opnd.offset())) {
...@@ -4330,6 +4340,31 @@ void TurboAssembler::SwapDouble(MemOperand src, MemOperand dst, ...@@ -4330,6 +4340,31 @@ void TurboAssembler::SwapDouble(MemOperand src, MemOperand dst,
StoreDouble(scratch_1, src); StoreDouble(scratch_1, src);
} }
void TurboAssembler::SwapSimd128(Simd128Register src, Simd128Register dst,
Simd128Register scratch) {
if (src == dst) return;
vlr(scratch, src, Condition(0), Condition(0), Condition(0));
vlr(src, dst, Condition(0), Condition(0), Condition(0));
vlr(dst, scratch, Condition(0), Condition(0), Condition(0));
}
void TurboAssembler::SwapSimd128(Simd128Register src, MemOperand dst,
Simd128Register scratch) {
DCHECK(!AreAliased(src, scratch));
vlr(scratch, src, Condition(0), Condition(0), Condition(0));
LoadSimd128(src, dst);
StoreSimd128(scratch, dst);
}
void TurboAssembler::SwapSimd128(MemOperand src, MemOperand dst,
Simd128Register scratch_0,
Simd128Register scratch_1) {
LoadSimd128(scratch_0, src);
LoadSimd128(scratch_1, dst);
StoreSimd128(scratch_0, dst);
StoreSimd128(scratch_1, src);
}
void TurboAssembler::ResetSpeculationPoisonRegister() { void TurboAssembler::ResetSpeculationPoisonRegister() {
mov(kSpeculationPoisonRegister, Operand(-1)); mov(kSpeculationPoisonRegister, Operand(-1));
} }
......
...@@ -413,6 +413,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -413,6 +413,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void LoadDouble(DoubleRegister dst, const MemOperand& opnd); void LoadDouble(DoubleRegister dst, const MemOperand& opnd);
void LoadFloat32(DoubleRegister dst, const MemOperand& opnd); void LoadFloat32(DoubleRegister dst, const MemOperand& opnd);
void LoadFloat32ConvertToDouble(DoubleRegister dst, const MemOperand& mem); void LoadFloat32ConvertToDouble(DoubleRegister dst, const MemOperand& mem);
void LoadSimd128(Simd128Register dst, const MemOperand& mem);
void AddFloat32(DoubleRegister dst, const MemOperand& opnd, void AddFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch); DoubleRegister scratch);
...@@ -444,6 +445,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -444,6 +445,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void StoreFloat32(DoubleRegister dst, const MemOperand& opnd); void StoreFloat32(DoubleRegister dst, const MemOperand& opnd);
void StoreDoubleAsFloat32(DoubleRegister src, const MemOperand& mem, void StoreDoubleAsFloat32(DoubleRegister src, const MemOperand& mem,
DoubleRegister scratch); DoubleRegister scratch);
void StoreSimd128(Simd128Register src, const MemOperand& mem);
void Branch(Condition c, const Operand& opnd); void Branch(Condition c, const Operand& opnd);
void BranchOnCount(Register r1, Label* l); void BranchOnCount(Register r1, Label* l);
...@@ -508,12 +510,21 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -508,12 +510,21 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
#endif #endif
} }
void push(DoubleRegister src) {
lay(sp, MemOperand(sp, -kPointerSize));
StoreDouble(src, MemOperand(sp));
}
void push(Register src) { void push(Register src) {
lay(sp, MemOperand(sp, -kPointerSize)); lay(sp, MemOperand(sp, -kPointerSize));
StoreP(src, MemOperand(sp)); StoreP(src, MemOperand(sp));
} }
void pop(DoubleRegister dst) {
LoadDouble(dst, MemOperand(sp));
la(sp, MemOperand(sp, kPointerSize));
}
void pop(Register dst) { void pop(Register dst) {
LoadP(dst, MemOperand(sp)); LoadP(dst, MemOperand(sp));
la(sp, MemOperand(sp, kPointerSize)); la(sp, MemOperand(sp, kPointerSize));
...@@ -774,6 +785,12 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -774,6 +785,12 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SwapDouble(DoubleRegister src, MemOperand dst, DoubleRegister scratch); void SwapDouble(DoubleRegister src, MemOperand dst, DoubleRegister scratch);
void SwapDouble(MemOperand src, MemOperand dst, DoubleRegister scratch_0, void SwapDouble(MemOperand src, MemOperand dst, DoubleRegister scratch_0,
DoubleRegister scratch_1); DoubleRegister scratch_1);
void SwapSimd128(Simd128Register src, Simd128Register dst,
Simd128Register scratch);
void SwapSimd128(Simd128Register src, MemOperand dst,
Simd128Register scratch);
void SwapSimd128(MemOperand src, MemOperand dst, Simd128Register scratch_0,
Simd128Register scratch_1);
// Cleanse pointer address on 31bit by zero out top bit. // Cleanse pointer address on 31bit by zero out top bit.
// This is a NOP on 64-bit. // This is a NOP on 64-bit.
......
This diff is collapsed.
...@@ -108,7 +108,8 @@ class Simulator : public SimulatorBase { ...@@ -108,7 +108,8 @@ class Simulator : public SimulatorBase {
// Accessors for register state. // Accessors for register state.
void set_register(int reg, uint64_t value); void set_register(int reg, uint64_t value);
uint64_t get_register(int reg) const; const uint64_t& get_register(int reg) const;
uint64_t& get_register(int reg);
template <typename T> template <typename T>
T get_low_register(int reg) const; T get_low_register(int reg) const;
template <typename T> template <typename T>
...@@ -119,20 +120,22 @@ class Simulator : public SimulatorBase { ...@@ -119,20 +120,22 @@ class Simulator : public SimulatorBase {
double get_double_from_register_pair(int reg); double get_double_from_register_pair(int reg);
void set_d_register_from_double(int dreg, const double dbl) { void set_d_register_from_double(int dreg, const double dbl) {
DCHECK(dreg >= 0 && dreg < kNumFPRs); DCHECK(dreg >= 0 && dreg < kNumFPRs);
*bit_cast<double*>(&fp_registers_[dreg]) = dbl; set_simd_register_by_lane<double>(dreg, 0, dbl);
} }
double get_double_from_d_register(int dreg) { double get_double_from_d_register(int dreg) {
DCHECK(dreg >= 0 && dreg < kNumFPRs); DCHECK(dreg >= 0 && dreg < kNumFPRs);
return *bit_cast<double*>(&fp_registers_[dreg]); return get_simd_register_by_lane<double>(dreg, 0);
} }
void set_d_register(int dreg, int64_t value) { void set_d_register(int dreg, int64_t value) {
DCHECK(dreg >= 0 && dreg < kNumFPRs); DCHECK(dreg >= 0 && dreg < kNumFPRs);
fp_registers_[dreg] = value; set_simd_register_by_lane<int64_t>(dreg, 0, value);
} }
int64_t get_d_register(int dreg) { int64_t get_d_register(int dreg) {
DCHECK(dreg >= 0 && dreg < kNumFPRs); DCHECK(dreg >= 0 && dreg < kNumFPRs);
return fp_registers_[dreg]; return get_simd_register_by_lane<int64_t>(dreg, 0);
} }
void set_d_register_from_float32(int dreg, const float f) { void set_d_register_from_float32(int dreg, const float f) {
...@@ -411,7 +414,43 @@ class Simulator : public SimulatorBase { ...@@ -411,7 +414,43 @@ class Simulator : public SimulatorBase {
// On z9 and higher and supported Linux on z Systems platforms, all registers // On z9 and higher and supported Linux on z Systems platforms, all registers
// are 64-bit, even in 31-bit mode. // are 64-bit, even in 31-bit mode.
uint64_t registers_[kNumGPRs]; uint64_t registers_[kNumGPRs];
int64_t fp_registers_[kNumFPRs]; union fpr_t {
int8_t int8[16];
uint8_t uint8[16];
int16_t int16[8];
uint16_t uint16[8];
int32_t int32[4];
uint32_t uint32[4];
int64_t int64[2];
uint64_t uint64[2];
float f32[4];
double f64[2];
};
fpr_t fp_registers_[kNumFPRs];
static constexpr fpr_t fp_zero = {{0}};
fpr_t& get_simd_register(int reg) {
return fp_registers_[reg];
}
void set_simd_register(int reg, const fpr_t& v) {
get_simd_register(reg) = v;
}
template<class T>
T& get_simd_register_by_lane(int reg, int lane) {
DCHECK_LE(lane, kSimd128Size / sizeof(T));
DCHECK_LT(reg, kNumFPRs);
DCHECK_GE(lane, 0);
DCHECK_GE(reg, 0);
return (reinterpret_cast<T*>(&get_simd_register(reg)))[lane];
}
template<class T>
void set_simd_register_by_lane(int reg, int lane, const T& value) {
get_simd_register_by_lane<T>(reg, lane) = value;
}
// Condition Code register. In S390, the last 4 bits are used. // Condition Code register. In S390, the last 4 bits are used.
int32_t condition_reg_; int32_t condition_reg_;
...@@ -461,10 +500,18 @@ class Simulator : public SimulatorBase { ...@@ -461,10 +500,18 @@ class Simulator : public SimulatorBase {
static void EvalTableInit(); static void EvalTableInit();
#define EVALUATE(name) int Evaluate_##name(Instruction* instr) #define EVALUATE(name) int Evaluate_##name(Instruction* instr)
#define EVALUATE_VRR_INSTRUCTIONS(name, op_name, op_value) EVALUATE(op_name); #define EVALUATE_VR_INSTRUCTIONS(name, op_name, op_value) EVALUATE(op_name);
S390_VRR_C_OPCODE_LIST(EVALUATE_VRR_INSTRUCTIONS) S390_VRR_A_OPCODE_LIST(EVALUATE_VR_INSTRUCTIONS)
S390_VRR_A_OPCODE_LIST(EVALUATE_VRR_INSTRUCTIONS) S390_VRR_C_OPCODE_LIST(EVALUATE_VR_INSTRUCTIONS)
#undef EVALUATE_VRR_INSTRUCTIONS S390_VRR_E_OPCODE_LIST(EVALUATE_VR_INSTRUCTIONS)
S390_VRX_OPCODE_LIST(EVALUATE_VR_INSTRUCTIONS)
S390_VRS_A_OPCODE_LIST(EVALUATE_VR_INSTRUCTIONS)
S390_VRS_B_OPCODE_LIST(EVALUATE_VR_INSTRUCTIONS)
S390_VRS_C_OPCODE_LIST(EVALUATE_VR_INSTRUCTIONS)
S390_VRR_B_OPCODE_LIST(EVALUATE_VR_INSTRUCTIONS)
S390_VRI_A_OPCODE_LIST(EVALUATE_VR_INSTRUCTIONS)
S390_VRI_C_OPCODE_LIST(EVALUATE_VR_INSTRUCTIONS)
#undef EVALUATE_VR_INSTRUCTIONS
EVALUATE(DUMY); EVALUATE(DUMY);
EVALUATE(BKPT); EVALUATE(BKPT);
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment