Commit 16bbc2fa authored by jyan's avatar jyan Committed by Commit bot

s390: optimize for int 64-bit operation and cleanup

R=joransiu@ca.ibm.com, bjaideep@ca.ibm.com

Review-Url: https://codereview.chromium.org/2722313003
Cr-Commit-Position: refs/heads/master@{#43527}
parent 12c2c153
This diff is collapsed.
......@@ -1844,18 +1844,42 @@ void Assembler::adb(DoubleRegister r1, const MemOperand& opnd) {
opnd.offset());
}
// Add Register-Storage (LB)
void Assembler::aeb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(AEB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
opnd.offset());
}
// Sub Register-Storage (LB)
void Assembler::seb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(SEB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
opnd.offset());
}
// Divide Register-Storage (LB)
void Assembler::ddb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(DDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
opnd.offset());
}
// Divide Register-Storage (LB)
void Assembler::deb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(DEB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
opnd.offset());
}
// Multiply Register-Storage (LB)
void Assembler::mdb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(MDB, Register::from_code(r1.code()), opnd.rb(), opnd.rx(),
opnd.offset());
}
// Multiply Register-Storage (LB)
void Assembler::meeb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(MEEB, Register::from_code(r1.code()), opnd.rb(), opnd.rx(),
opnd.offset());
}
// Subtract Register-Storage (LB)
void Assembler::sdb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(SDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
......
......@@ -1203,9 +1203,13 @@ class Assembler : public AssemblerBase {
// Floating Point Arithmetic Instructions
void adb(DoubleRegister r1, const MemOperand& opnd);
void aeb(DoubleRegister r1, const MemOperand& opnd);
void sdb(DoubleRegister r1, const MemOperand& opnd);
void seb(DoubleRegister r1, const MemOperand& opnd);
void mdb(DoubleRegister r1, const MemOperand& opnd);
void meeb(DoubleRegister r1, const MemOperand& opnd);
void ddb(DoubleRegister r1, const MemOperand& opnd);
void deb(DoubleRegister r1, const MemOperand& opnd);
void sqdb(DoubleRegister r1, const MemOperand& opnd);
void ldeb(DoubleRegister r1, const MemOperand& opnd);
......
......@@ -1436,6 +1436,9 @@ bool Decoder::DecodeSixByte(Instruction* instr) {
case ADB:
Format(instr, "adb\t'f1,'d1('r2d, 'r3)");
break;
case AEB:
Format(instr, "aeb\t'f1,'d1('r2d, 'r3)");
break;
case CDB:
Format(instr, "cdb\t'f1,'d1('r2d, 'r3)");
break;
......@@ -1445,12 +1448,21 @@ bool Decoder::DecodeSixByte(Instruction* instr) {
case SDB:
Format(instr, "sdb\t'r1,'d1('r2d, 'r3)");
break;
case SEB:
Format(instr, "seb\t'r1,'d1('r2d, 'r3)");
break;
case MDB:
Format(instr, "mdb\t'r1,'d1('r2d, 'r3)");
break;
case MEEB:
Format(instr, "meeb\t'r1,'d1('r2d, 'r3)");
break;
case DDB:
Format(instr, "ddb\t'r1,'d1('r2d, 'r3)");
break;
case DEB:
Format(instr, "deb\t'r1,'d1('r2d, 'r3)");
break;
case SQDB:
Format(instr, "sqdb\t'r1,'d1('r2d, 'r3)");
break;
......
......@@ -3374,13 +3374,6 @@ void MacroAssembler::Div32(Register dst, Register src1, Register src2) {
Generate_Div32(dsgfr);
}
void MacroAssembler::Div32(Register dst, Register src1, const Operand& src2) {
USE(dst);
USE(src1);
USE(src2);
UNREACHABLE();
}
#undef Generate_Div32
#define Generate_DivU32(instr) \
......@@ -3400,14 +3393,44 @@ void MacroAssembler::DivU32(Register dst, Register src1, Register src2) {
Generate_DivU32(dlr);
}
void MacroAssembler::DivU32(Register dst, Register src1, const Operand& src2) {
USE(dst);
USE(src1);
USE(src2);
UNREACHABLE();
#undef Generate_DivU32
#define Generate_Div64(instr) \
{ \
lgr(r1, src1); \
instr(r0, src2); \
lgr(dst, r1); \
}
void MacroAssembler::Div64(Register dst, Register src1,
const MemOperand& src2) {
Generate_Div64(dsg);
}
#undef Generate_DivU32
void MacroAssembler::Div64(Register dst, Register src1, Register src2) {
Generate_Div64(dsgr);
}
#undef Generate_Div64
#define Generate_DivU64(instr) \
{ \
lgr(r1, src1); \
lghi(r0, Operand::Zero()); \
instr(r0, src2); \
lgr(dst, r1); \
}
void MacroAssembler::DivU64(Register dst, Register src1,
const MemOperand& src2) {
Generate_DivU64(dlg);
}
void MacroAssembler::DivU64(Register dst, Register src1, Register src2) {
Generate_DivU64(dlgr);
}
#undef Generate_DivU64
#define Generate_Mod32(instr) \
{ \
......@@ -3425,13 +3448,6 @@ void MacroAssembler::Mod32(Register dst, Register src1, Register src2) {
Generate_Mod32(dsgfr);
}
void MacroAssembler::Mod32(Register dst, Register src1, const Operand& src2) {
USE(dst);
USE(src1);
USE(src2);
UNREACHABLE();
}
#undef Generate_Mod32
#define Generate_ModU32(instr) \
......@@ -3451,14 +3467,44 @@ void MacroAssembler::ModU32(Register dst, Register src1, Register src2) {
Generate_ModU32(dlr);
}
void MacroAssembler::ModU32(Register dst, Register src1, const Operand& src2) {
USE(dst);
USE(src1);
USE(src2);
UNREACHABLE();
#undef Generate_ModU32
#define Generate_Mod64(instr) \
{ \
lgr(r1, src1); \
instr(r0, src2); \
lgr(dst, r0); \
}
void MacroAssembler::Mod64(Register dst, Register src1,
const MemOperand& src2) {
Generate_Mod64(dsg);
}
#undef Generate_ModU32
void MacroAssembler::Mod64(Register dst, Register src1, Register src2) {
Generate_Mod64(dsgr);
}
#undef Generate_Mod64
#define Generate_ModU64(instr) \
{ \
lgr(r1, src1); \
lghi(r0, Operand::Zero()); \
instr(r0, src2); \
lgr(dst, r0); \
}
void MacroAssembler::ModU64(Register dst, Register src1,
const MemOperand& src2) {
Generate_ModU64(dlg);
}
void MacroAssembler::ModU64(Register dst, Register src1, Register src2) {
Generate_ModU64(dlgr);
}
#undef Generate_ModU64
void MacroAssembler::MulP(Register dst, const Operand& opnd) {
#if V8_TARGET_ARCH_S390X
......@@ -5000,6 +5046,97 @@ void MacroAssembler::StoreDoubleAsFloat32(DoubleRegister src,
StoreFloat32(scratch, mem);
}
void MacroAssembler::AddFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch) {
if (is_uint12(opnd.offset())) {
aeb(dst, opnd);
} else {
ley(scratch, opnd);
aebr(dst, scratch);
}
}
void MacroAssembler::AddFloat64(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch) {
if (is_uint12(opnd.offset())) {
adb(dst, opnd);
} else {
ldy(scratch, opnd);
adbr(dst, scratch);
}
}
void MacroAssembler::SubFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch) {
if (is_uint12(opnd.offset())) {
seb(dst, opnd);
} else {
ley(scratch, opnd);
sebr(dst, scratch);
}
}
void MacroAssembler::SubFloat64(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch) {
if (is_uint12(opnd.offset())) {
sdb(dst, opnd);
} else {
ldy(scratch, opnd);
sdbr(dst, scratch);
}
}
void MacroAssembler::MulFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch) {
if (is_uint12(opnd.offset())) {
meeb(dst, opnd);
} else {
ley(scratch, opnd);
meebr(dst, scratch);
}
}
void MacroAssembler::MulFloat64(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch) {
if (is_uint12(opnd.offset())) {
mdb(dst, opnd);
} else {
ldy(scratch, opnd);
mdbr(dst, scratch);
}
}
void MacroAssembler::DivFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch) {
if (is_uint12(opnd.offset())) {
deb(dst, opnd);
} else {
ley(scratch, opnd);
debr(dst, scratch);
}
}
void MacroAssembler::DivFloat64(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch) {
if (is_uint12(opnd.offset())) {
ddb(dst, opnd);
} else {
ldy(scratch, opnd);
ddbr(dst, scratch);
}
}
void MacroAssembler::LoadFloat32ToDouble(DoubleRegister dst,
const MemOperand& opnd,
DoubleRegister scratch) {
if (is_uint12(opnd.offset())) {
ldeb(dst, opnd);
} else {
ley(scratch, opnd);
ldebr(dst, scratch);
}
}
// Variable length depending on whether offset fits into immediate field
// MemOperand of RX or RXY format
void MacroAssembler::StoreW(Register src, const MemOperand& mem,
......
......@@ -342,18 +342,22 @@ class MacroAssembler : public Assembler {
void DivP(Register dividend, Register divider);
void Div32(Register dst, Register src1, const MemOperand& src2);
void Div32(Register dst, Register src1, Register src2);
void Div32(Register dst, Register src1, const Operand& src2);
void DivU32(Register dst, Register src1, const MemOperand& src2);
void DivU32(Register dst, Register src1, Register src2);
void DivU32(Register dst, Register src1, const Operand& src2);
void Div64(Register dst, Register src1, const MemOperand& src2);
void Div64(Register dst, Register src1, Register src2);
void DivU64(Register dst, Register src1, const MemOperand& src2);
void DivU64(Register dst, Register src1, Register src2);
// Mod
void Mod32(Register dst, Register src1, const MemOperand& src2);
void Mod32(Register dst, Register src1, Register src2);
void Mod32(Register dst, Register src1, const Operand& src2);
void ModU32(Register dst, Register src1, const MemOperand& src2);
void ModU32(Register dst, Register src1, Register src2);
void ModU32(Register dst, Register src1, const Operand& src2);
void Mod64(Register dst, Register src1, const MemOperand& src2);
void Mod64(Register dst, Register src1, Register src2);
void ModU64(Register dst, Register src1, const MemOperand& src2);
void ModU64(Register dst, Register src1, Register src2);
// Square root
void Sqrt(DoubleRegister result, DoubleRegister input);
......@@ -408,6 +412,25 @@ class MacroAssembler : public Assembler {
void LoadFloat32(DoubleRegister dst, const MemOperand& opnd);
void LoadFloat32ConvertToDouble(DoubleRegister dst, const MemOperand& mem);
void AddFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch);
void AddFloat64(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch);
void SubFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch);
void SubFloat64(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch);
void MulFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch);
void MulFloat64(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch);
void DivFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch);
void DivFloat64(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch);
void LoadFloat32ToDouble(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch);
// Load On Condition
void LoadOnConditionP(Condition cond, Register dst, Register src);
......
......@@ -8770,8 +8770,6 @@ EVALUATE(DEBR) {
float fr2_val = get_float32_from_d_register(r2);
fr1_val /= fr2_val;
set_d_register_from_float32(r1, fr1_val);
SetS390ConditionCode<float>(fr1_val, 0);
return length;
}
......@@ -8871,7 +8869,6 @@ EVALUATE(MEEBR) {
float fr2_val = get_float32_from_d_register(r2);
fr1_val *= fr2_val;
set_d_register_from_float32(r1, fr1_val);
SetS390ConditionCode<float>(fr1_val, 0);
return length;
}
......@@ -8923,7 +8920,6 @@ EVALUATE(MDBR) {
double r2_val = get_double_from_d_register(r2);
r1_val *= r2_val;
set_d_register_from_double(r1, r1_val);
SetS390ConditionCode<double>(r1_val, 0);
return length;
}
......@@ -8934,7 +8930,6 @@ EVALUATE(DDBR) {
double r2_val = get_double_from_d_register(r2);
r1_val /= r2_val;
set_d_register_from_double(r1, r1_val);
SetS390ConditionCode<double>(r1_val, 0);
return length;
}
......@@ -10440,12 +10435,14 @@ EVALUATE(DLGR) {
dividend += get_register(r1 + 1);
uint64_t remainder = dividend % r2_val;
uint64_t quotient = dividend / r2_val;
r1_val = remainder;
set_register(r1, remainder);
set_register(r1 + 1, quotient);
return length;
#else
// 32 bit arch doesn't support __int128 type
USE(instr);
UNREACHABLE();
return 0;
#endif
}
......@@ -10931,8 +10928,10 @@ EVALUATE(AG) {
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
int64_t alu_out = get_register(r1);
int64_t mem_val = ReadDW(b2_val + x2_val + d2);
bool isOF = CheckOverflowForIntAdd(alu_out, mem_val, int64_t);
alu_out += mem_val;
SetS390ConditionCode<int32_t>(alu_out, 0);
SetS390ConditionCode<int64_t>(alu_out, 0);
SetS390OverflowCode(isOF);
set_register(r1, alu_out);
return length;
}
......@@ -10944,8 +10943,10 @@ EVALUATE(SG) {
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
int64_t alu_out = get_register(r1);
int64_t mem_val = ReadDW(b2_val + x2_val + d2);
bool isOF = CheckOverflowForIntSub(alu_out, mem_val, int64_t);
alu_out -= mem_val;
SetS390ConditionCode<int32_t>(alu_out, 0);
SetS390OverflowCode(isOF);
set_register(r1, alu_out);
return length;
}
......@@ -10999,9 +11000,19 @@ EVALUATE(MSG) {
}
EVALUATE(DSG) {
UNIMPLEMENTED();
USE(instr);
return 0;
DCHECK_OPCODE(DSG);
DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
DCHECK(r1 % 2 == 0);
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
intptr_t d2_val = d2;
int64_t mem_val = ReadDW(b2_val + d2_val + x2_val);
int64_t r1_val = get_register(r1 + 1);
int64_t quotient = r1_val / mem_val;
int64_t remainder = r1_val % mem_val;
set_register(r1, remainder);
set_register(r1 + 1, quotient);
return length;
}
EVALUATE(CVBG) {
......@@ -11609,9 +11620,27 @@ EVALUATE(MLG) {
}
EVALUATE(DLG) {
UNIMPLEMENTED();
DCHECK_OPCODE(DLG);
#ifdef V8_TARGET_ARCH_S390X
DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
uint64_t r1_val = get_register(r1);
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
DCHECK(r1 % 2 == 0);
unsigned __int128 dividend = static_cast<unsigned __int128>(r1_val) << 64;
dividend += get_register(r1 + 1);
int64_t mem_val = ReadDW(b2_val + x2_val + d2);
uint64_t remainder = dividend % mem_val;
uint64_t quotient = dividend / mem_val;
set_register(r1, remainder);
set_register(r1 + 1, quotient);
return length;
#else
// 32 bit arch doesn't support __int128 type
USE(instr);
UNREACHABLE();
return 0;
#endif
}
EVALUATE(ALCG) {
......@@ -12514,16 +12543,14 @@ EVALUATE(CIB) {
EVALUATE(LDEB) {
DCHECK_OPCODE(LDEB);
// Load Float
DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
int rb = b2;
int rx = x2;
int offset = d2;
int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
double ret =
static_cast<double>(*reinterpret_cast<float*>(rx_val + rb_val + offset));
set_d_register_from_double(r1, ret);
float fval = ReadFloat(rx_val + rb_val + offset);
set_d_register_from_double(r1, static_cast<double>(fval));
return length;
}
......@@ -12565,15 +12592,31 @@ EVALUATE(CEB) {
}
EVALUATE(AEB) {
UNIMPLEMENTED();
USE(instr);
return 0;
DCHECK_OPCODE(AEB);
DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
intptr_t d2_val = d2;
float r1_val = get_float32_from_d_register(r1);
float fval = ReadFloat(b2_val + x2_val + d2_val);
r1_val += fval;
set_d_register_from_float32(r1, r1_val);
SetS390ConditionCode<float>(r1_val, 0);
return length;
}
EVALUATE(SEB) {
UNIMPLEMENTED();
USE(instr);
return 0;
DCHECK_OPCODE(SEB);
DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
intptr_t d2_val = d2;
float r1_val = get_float32_from_d_register(r1);
float fval = ReadFloat(b2_val + x2_val + d2_val);
r1_val -= fval;
set_d_register_from_float32(r1, r1_val);
SetS390ConditionCode<float>(r1_val, 0);
return length;
}
EVALUATE(MDEB) {
......@@ -12583,9 +12626,16 @@ EVALUATE(MDEB) {
}
EVALUATE(DEB) {
UNIMPLEMENTED();
USE(instr);
return 0;
DCHECK_OPCODE(DEB);
DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
intptr_t d2_val = d2;
float r1_val = get_float32_from_d_register(r1);
float fval = ReadFloat(b2_val + x2_val + d2_val);
r1_val /= fval;
set_d_register_from_float32(r1, r1_val);
return length;
}
EVALUATE(MAEB) {
......@@ -12638,9 +12688,16 @@ EVALUATE(SQDB) {
}
EVALUATE(MEEB) {
UNIMPLEMENTED();
USE(instr);
return 0;
DCHECK_OPCODE(MEEB);
DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
intptr_t d2_val = d2;
float r1_val = get_float32_from_d_register(r1);
float fval = ReadFloat(b2_val + x2_val + d2_val);
r1_val *= fval;
set_d_register_from_float32(r1, r1_val);
return length;
}
EVALUATE(KDB) {
......@@ -12701,7 +12758,6 @@ EVALUATE(MDB) {
double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
r1_val *= dbl_val;
set_d_register_from_double(r1, r1_val);
SetS390ConditionCode<double>(r1_val, 0);
return length;
}
......@@ -12715,7 +12771,6 @@ EVALUATE(DDB) {
double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
r1_val /= dbl_val;
set_d_register_from_double(r1, r1_val);
SetS390ConditionCode<double>(r1_val, 0);
return length;
}
......
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