Commit 2dab40cc authored by jyan's avatar jyan Committed by Commit bot

s390: use new mul instruction

R=joransiu@ca.ibm.com, bjaideep@ca.ibm.com, danno@chromium.org, bmeurer@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/2691893002
Cr-Commit-Position: refs/heads/master@{#43166}
parent d891b500
...@@ -1287,8 +1287,12 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { ...@@ -1287,8 +1287,12 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
__ bge(&done, Label::kNear); __ bge(&done, Label::kNear);
// If there is no remainder then we are done. // If there is no remainder then we are done.
__ lr(scratch, result); if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) {
__ msr(scratch, divisor); __ msrkc(scratch, result, divisor);
} else {
__ lr(scratch, result);
__ msr(scratch, divisor);
}
__ Cmp32(dividend, scratch); __ Cmp32(dividend, scratch);
__ beq(&done, Label::kNear); __ beq(&done, Label::kNear);
...@@ -1419,36 +1423,48 @@ void LCodeGen::DoMulI(LMulI* instr) { ...@@ -1419,36 +1423,48 @@ void LCodeGen::DoMulI(LMulI* instr) {
Register right = ToRegister(right_op); Register right = ToRegister(right_op);
if (can_overflow) { if (can_overflow) {
#if V8_TARGET_ARCH_S390X if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) {
// result = left * right. // result = left * right.
if (instr->hydrogen()->representation().IsSmi()) { if (instr->hydrogen()->representation().IsSmi()) {
__ SmiUntag(result, left); __ SmiUntag(scratch, right);
__ SmiUntag(scratch, right); __ MulPWithCondition(result, left, scratch);
__ msgr(result, scratch); } else {
__ msrkc(result, left, right);
__ LoadW(result, result);
}
DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow);
} else { } else {
__ LoadRR(result, left); #if V8_TARGET_ARCH_S390X
__ msgr(result, right); // result = left * right.
} if (instr->hydrogen()->representation().IsSmi()) {
__ TestIfInt32(result, r0); __ SmiUntag(result, left);
DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); __ SmiUntag(scratch, right);
if (instr->hydrogen()->representation().IsSmi()) { __ msgr(result, scratch);
__ SmiTag(result); } else {
} __ LoadRR(result, left);
__ msgr(result, right);
}
__ TestIfInt32(result, r0);
DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow);
if (instr->hydrogen()->representation().IsSmi()) {
__ SmiTag(result);
}
#else #else
// r0:scratch = scratch * right
if (instr->hydrogen()->representation().IsSmi()) {
__ SmiUntag(scratch, left);
__ mr_z(r0, right);
__ LoadRR(result, scratch);
} else {
// r0:scratch = scratch * right // r0:scratch = scratch * right
__ LoadRR(scratch, left); if (instr->hydrogen()->representation().IsSmi()) {
__ mr_z(r0, right); __ SmiUntag(scratch, left);
__ LoadRR(result, scratch); __ mr_z(r0, right);
} __ LoadRR(result, scratch);
__ TestIfInt32(r0, result, scratch); } else {
DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); // r0:scratch = scratch * right
__ LoadRR(scratch, left);
__ mr_z(r0, right);
__ LoadRR(result, scratch);
}
__ TestIfInt32(r0, result, scratch);
DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow);
#endif #endif
}
} else { } else {
if (instr->hydrogen()->representation().IsSmi()) { if (instr->hydrogen()->representation().IsSmi()) {
__ SmiUntag(result, left); __ SmiUntag(result, left);
......
...@@ -1582,34 +1582,42 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, ...@@ -1582,34 +1582,42 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
} }
case Token::MUL: { case Token::MUL: {
Label mul_zero; Label mul_zero;
if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) {
__ SmiUntag(ip, right);
__ MulPWithCondition(scratch2, ip, left);
__ b(overflow, &stub_call);
__ beq(&mul_zero, Label::kNear);
__ LoadRR(right, scratch2);
} else {
#if V8_TARGET_ARCH_S390X #if V8_TARGET_ARCH_S390X
// Remove tag from both operands. // Remove tag from both operands.
__ SmiUntag(ip, right); __ SmiUntag(ip, right);
__ SmiUntag(scratch2, left); __ SmiUntag(scratch2, left);
__ mr_z(scratch1, ip); __ mr_z(scratch1, ip);
// Check for overflowing the smi range - no overflow if higher 33 bits of // Check for overflowing the smi range - no overflow if higher 33 bits
// the result are identical. // of the result are identical.
__ lr(ip, scratch2); // 32 bit load __ lr(ip, scratch2); // 32 bit load
__ sra(ip, Operand(31)); __ sra(ip, Operand(31));
__ cr_z(ip, scratch1); // 32 bit compare __ cr_z(ip, scratch1); // 32 bit compare
__ bne(&stub_call); __ bne(&stub_call);
#else #else
__ SmiUntag(ip, right); __ SmiUntag(ip, right);
__ LoadRR(scratch2, left); // load into low order of reg pair __ LoadRR(scratch2, left); // load into low order of reg pair
__ mr_z(scratch1, ip); // R4:R5 = R5 * ip __ mr_z(scratch1, ip); // R4:R5 = R5 * ip
// Check for overflowing the smi range - no overflow if higher 33 bits of // Check for overflowing the smi range - no overflow if higher 33 bits
// the result are identical. // of the result are identical.
__ TestIfInt32(scratch1, scratch2, ip); __ TestIfInt32(scratch1, scratch2, ip);
__ bne(&stub_call); __ bne(&stub_call);
#endif #endif
// Go slow on zero result to handle -0. // Go slow on zero result to handle -0.
__ chi(scratch2, Operand::Zero()); __ chi(scratch2, Operand::Zero());
__ beq(&mul_zero, Label::kNear); __ beq(&mul_zero, Label::kNear);
#if V8_TARGET_ARCH_S390X #if V8_TARGET_ARCH_S390X
__ SmiTag(right, scratch2); __ SmiTag(right, scratch2);
#else #else
__ LoadRR(right, scratch2); __ LoadRR(right, scratch2);
#endif #endif
}
__ b(&done); __ b(&done);
// We need -0 if we were multiplying a negative number with 0 to get 0. // We need -0 if we were multiplying a negative number with 0 to get 0.
// We know one of them was zero. // We know one of them was zero.
......
...@@ -807,6 +807,7 @@ enum CpuFeature { ...@@ -807,6 +807,7 @@ enum CpuFeature {
GENERAL_INSTR_EXT, GENERAL_INSTR_EXT,
FLOATING_POINT_EXT, FLOATING_POINT_EXT,
VECTOR_FACILITY, VECTOR_FACILITY,
MISC_INSTR_EXT2,
NUMBER_OF_CPU_FEATURES, NUMBER_OF_CPU_FEATURES,
......
...@@ -166,14 +166,18 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { ...@@ -166,14 +166,18 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
if (facilities[2] & (one << (63 - (129 - 128)))) { if (facilities[2] & (one << (63 - (129 - 128)))) {
supported_ |= (1u << VECTOR_FACILITY); supported_ |= (1u << VECTOR_FACILITY);
} }
// Test for Miscellaneous Instruction Extension Facility - Bit 58
if (facilities[0] & (1lu << (63 - 58))) {
supported_ |= (1u << MISC_INSTR_EXT2);
}
} }
#else #else
// All distinct ops instructions can be simulated // All distinct ops instructions can be simulated
supported_ |= (1u << DISTINCT_OPS); supported_ |= (1u << DISTINCT_OPS);
// RISBG can be simulated // RISBG can be simulated
supported_ |= (1u << GENERAL_INSTR_EXT); supported_ |= (1u << GENERAL_INSTR_EXT);
supported_ |= (1u << FLOATING_POINT_EXT); supported_ |= (1u << FLOATING_POINT_EXT);
supported_ |= (1u << MISC_INSTR_EXT2);
USE(performSTFLE); // To avoid assert USE(performSTFLE); // To avoid assert
supported_ |= (1u << VECTOR_FACILITY); supported_ |= (1u << VECTOR_FACILITY);
#endif #endif
...@@ -198,6 +202,7 @@ void CpuFeatures::PrintFeatures() { ...@@ -198,6 +202,7 @@ void CpuFeatures::PrintFeatures() {
printf("GENERAL_INSTR=%d\n", CpuFeatures::IsSupported(GENERAL_INSTR_EXT)); printf("GENERAL_INSTR=%d\n", CpuFeatures::IsSupported(GENERAL_INSTR_EXT));
printf("DISTINCT_OPS=%d\n", CpuFeatures::IsSupported(DISTINCT_OPS)); printf("DISTINCT_OPS=%d\n", CpuFeatures::IsSupported(DISTINCT_OPS));
printf("VECTOR_FACILITY=%d\n", CpuFeatures::IsSupported(VECTOR_FACILITY)); printf("VECTOR_FACILITY=%d\n", CpuFeatures::IsSupported(VECTOR_FACILITY));
printf("MISC_INSTR_EXT2=%d\n", CpuFeatures::IsSupported(MISC_INSTR_EXT2));
} }
Register ToRegister(int num) { Register ToRegister(int num) {
...@@ -1510,6 +1515,16 @@ void Assembler::mhi(Register r1, const Operand& opnd) { ...@@ -1510,6 +1515,16 @@ void Assembler::mhi(Register r1, const Operand& opnd) {
ri_form(MHI, r1, opnd); ri_form(MHI, r1, opnd);
} }
// Multiply Single Register (32)
void Assembler::msrkc(Register r1, Register r2, Register r3) {
rrf1_form(MSRKC, r1, r2, r3);
}
// Multiply Single Register (64)
void Assembler::msgrkc(Register r1, Register r2, Register r3) {
rrf1_form(MSGRKC, r1, r2, r3);
}
// ---------------------------- // ----------------------------
// 64-bit Multiply Instructions // 64-bit Multiply Instructions
// ---------------------------- // ----------------------------
......
...@@ -1160,6 +1160,8 @@ class Assembler : public AssemblerBase { ...@@ -1160,6 +1160,8 @@ class Assembler : public AssemblerBase {
// 32-bit Multiply Instructions // 32-bit Multiply Instructions
void mhi(Register r1, const Operand& opnd); void mhi(Register r1, const Operand& opnd);
void msrkc(Register r1, Register r2, Register r3);
void msgrkc(Register r1, Register r2, Register r3);
// 64-bit Multiply Instructions // 64-bit Multiply Instructions
void mghi(Register r1, const Operand& opnd); void mghi(Register r1, const Operand& opnd);
......
...@@ -271,6 +271,8 @@ typedef uint64_t SixByteInstr; ...@@ -271,6 +271,8 @@ typedef uint64_t SixByteInstr;
V(sdtra, SDTRA, 0xB3D3) /* type = RRF_A SUBTRACT (long DFP) */ \ V(sdtra, SDTRA, 0xB3D3) /* type = RRF_A SUBTRACT (long DFP) */ \
V(mxtr, MXTR, 0xB3D8) /* type = RRF_A MULTIPLY (extended DFP) */ \ V(mxtr, MXTR, 0xB3D8) /* type = RRF_A MULTIPLY (extended DFP) */ \
V(mxtra, MXTRA, 0xB3D8) /* type = RRF_A MULTIPLY (extended DFP) */ \ V(mxtra, MXTRA, 0xB3D8) /* type = RRF_A MULTIPLY (extended DFP) */ \
V(msrkc, MSRKC, 0xB9FD) /* type = RRF_A MULTIPLY (32)*/ \
V(msgrkc, MSGRKC, 0xB9ED) /* type = RRF_A MULTIPLY (64)*/ \
V(dxtr, DXTR, 0xB3D9) /* type = RRF_A DIVIDE (extended DFP) */ \ V(dxtr, DXTR, 0xB3D9) /* type = RRF_A DIVIDE (extended DFP) */ \
V(dxtra, DXTRA, 0xB3D9) /* type = RRF_A DIVIDE (extended DFP) */ \ V(dxtra, DXTRA, 0xB3D9) /* type = RRF_A DIVIDE (extended DFP) */ \
V(axtr, AXTR, 0xB3DA) /* type = RRF_A ADD (extended DFP) */ \ V(axtr, AXTR, 0xB3DA) /* type = RRF_A ADD (extended DFP) */ \
......
...@@ -775,6 +775,9 @@ bool Decoder::DecodeFourByte(Instruction* instr) { ...@@ -775,6 +775,9 @@ bool Decoder::DecodeFourByte(Instruction* instr) {
case MSR: case MSR:
Format(instr, "msr\t'r5,'r6"); Format(instr, "msr\t'r5,'r6");
break; break;
case MSRKC:
Format(instr, "msrkc\t'r5,'r6,'r3");
break;
case LGBR: case LGBR:
Format(instr, "lgbr\t'r5,'r6"); Format(instr, "lgbr\t'r5,'r6");
break; break;
...@@ -784,6 +787,9 @@ bool Decoder::DecodeFourByte(Instruction* instr) { ...@@ -784,6 +787,9 @@ bool Decoder::DecodeFourByte(Instruction* instr) {
case MSGR: case MSGR:
Format(instr, "msgr\t'r5,'r6"); Format(instr, "msgr\t'r5,'r6");
break; break;
case MSGRKC:
Format(instr, "msgrkc\t'r5,'r6,'r3");
break;
case DSGR: case DSGR:
Format(instr, "dsgr\t'r5,'r6"); Format(instr, "dsgr\t'r5,'r6");
break; break;
......
...@@ -3340,13 +3340,17 @@ void MacroAssembler::Mul64(Register dst, const Operand& src1) { ...@@ -3340,13 +3340,17 @@ void MacroAssembler::Mul64(Register dst, const Operand& src1) {
} }
void MacroAssembler::Mul(Register dst, Register src1, Register src2) { void MacroAssembler::Mul(Register dst, Register src1, Register src2) {
if (dst.is(src2)) { if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) {
MulP(dst, src1); MulPWithCondition(dst, src1, src2);
} else if (dst.is(src1)) {
MulP(dst, src2);
} else { } else {
Move(dst, src1); if (dst.is(src2)) {
MulP(dst, src2); MulP(dst, src1);
} else if (dst.is(src1)) {
MulP(dst, src2);
} else {
Move(dst, src1);
MulP(dst, src2);
}
} }
} }
...@@ -3478,6 +3482,16 @@ void MacroAssembler::MulP(Register dst, Register src) { ...@@ -3478,6 +3482,16 @@ void MacroAssembler::MulP(Register dst, Register src) {
#endif #endif
} }
void MacroAssembler::MulPWithCondition(Register dst, Register src1,
Register src2) {
CHECK(CpuFeatures::IsSupported(MISC_INSTR_EXT2));
#if V8_TARGET_ARCH_S390X
msgrkc(dst, src1, src2);
#else
msrkc(dst, src1, src2);
#endif
}
void MacroAssembler::MulP(Register dst, const MemOperand& opnd) { void MacroAssembler::MulP(Register dst, const MemOperand& opnd) {
#if V8_TARGET_ARCH_S390X #if V8_TARGET_ARCH_S390X
if (is_uint16(opnd.offset())) { if (is_uint16(opnd.offset())) {
......
...@@ -336,6 +336,7 @@ class MacroAssembler : public Assembler { ...@@ -336,6 +336,7 @@ class MacroAssembler : public Assembler {
void Mul64(Register dst, const MemOperand& src1); void Mul64(Register dst, const MemOperand& src1);
void Mul64(Register dst, Register src1); void Mul64(Register dst, Register src1);
void Mul64(Register dst, const Operand& src1); void Mul64(Register dst, const Operand& src1);
void MulPWithCondition(Register dst, Register src1, Register src2);
// Divide // Divide
void DivP(Register dividend, Register divider); void DivP(Register dividend, Register divider);
......
...@@ -985,6 +985,7 @@ void Simulator::EvalTableInit() { ...@@ -985,6 +985,7 @@ void Simulator::EvalTableInit() {
EvalTable[SAR] = &Simulator::Evaluate_SAR; EvalTable[SAR] = &Simulator::Evaluate_SAR;
EvalTable[EAR] = &Simulator::Evaluate_EAR; EvalTable[EAR] = &Simulator::Evaluate_EAR;
EvalTable[MSR] = &Simulator::Evaluate_MSR; EvalTable[MSR] = &Simulator::Evaluate_MSR;
EvalTable[MSRKC] = &Simulator::Evaluate_MSRKC;
EvalTable[MVST] = &Simulator::Evaluate_MVST; EvalTable[MVST] = &Simulator::Evaluate_MVST;
EvalTable[CUSE] = &Simulator::Evaluate_CUSE; EvalTable[CUSE] = &Simulator::Evaluate_CUSE;
EvalTable[SRST] = &Simulator::Evaluate_SRST; EvalTable[SRST] = &Simulator::Evaluate_SRST;
...@@ -1158,6 +1159,7 @@ void Simulator::EvalTableInit() { ...@@ -1158,6 +1159,7 @@ void Simulator::EvalTableInit() {
EvalTable[ALGR] = &Simulator::Evaluate_ALGR; EvalTable[ALGR] = &Simulator::Evaluate_ALGR;
EvalTable[SLGR] = &Simulator::Evaluate_SLGR; EvalTable[SLGR] = &Simulator::Evaluate_SLGR;
EvalTable[MSGR] = &Simulator::Evaluate_MSGR; EvalTable[MSGR] = &Simulator::Evaluate_MSGR;
EvalTable[MSGRKC] = &Simulator::Evaluate_MSGRKC;
EvalTable[DSGR] = &Simulator::Evaluate_DSGR; EvalTable[DSGR] = &Simulator::Evaluate_DSGR;
EvalTable[LRVGR] = &Simulator::Evaluate_LRVGR; EvalTable[LRVGR] = &Simulator::Evaluate_LRVGR;
EvalTable[LPGFR] = &Simulator::Evaluate_LPGFR; EvalTable[LPGFR] = &Simulator::Evaluate_LPGFR;
...@@ -8471,6 +8473,21 @@ EVALUATE(MSR) { ...@@ -8471,6 +8473,21 @@ EVALUATE(MSR) {
return length; return length;
} }
EVALUATE(MSRKC) {
DCHECK_OPCODE(MSRKC);
DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
int32_t r2_val = get_low_register<int32_t>(r2);
int32_t r3_val = get_low_register<int32_t>(r3);
int64_t result64 =
static_cast<int64_t>(r2_val) * static_cast<int64_t>(r3_val);
int32_t result32 = static_cast<int32_t>(result64);
bool isOF = (static_cast<int64_t>(result32) != result64);
SetS390ConditionCode<int32_t>(result32, 0);
SetS390OverflowCode(isOF);
set_low_register(r1, result32);
return length;
}
EVALUATE(MVST) { EVALUATE(MVST) {
UNIMPLEMENTED(); UNIMPLEMENTED();
USE(instr); USE(instr);
...@@ -9996,6 +10013,20 @@ EVALUATE(MSGR) { ...@@ -9996,6 +10013,20 @@ EVALUATE(MSGR) {
return length; return length;
} }
EVALUATE(MSGRKC) {
DCHECK_OPCODE(MSGRKC);
DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
int64_t r2_val = get_register(r2);
int64_t r3_val = get_register(r3);
volatile int64_t result64 = r2_val * r3_val;
bool isOF = ((r2_val == -1 && result64 == (static_cast<int64_t>(1L) << 63)) ||
(r2_val != 0 && result64 / r2_val != r3_val));
SetS390ConditionCode<int64_t>(result64, 0);
SetS390OverflowCode(isOF);
set_register(r1, result64);
return length;
}
EVALUATE(DSGR) { EVALUATE(DSGR) {
DCHECK_OPCODE(DSGR); DCHECK_OPCODE(DSGR);
DECODE_RRE_INSTRUCTION(r1, r2); DECODE_RRE_INSTRUCTION(r1, r2);
......
...@@ -758,6 +758,7 @@ class Simulator { ...@@ -758,6 +758,7 @@ class Simulator {
EVALUATE(SAR); EVALUATE(SAR);
EVALUATE(EAR); EVALUATE(EAR);
EVALUATE(MSR); EVALUATE(MSR);
EVALUATE(MSRKC);
EVALUATE(MVST); EVALUATE(MVST);
EVALUATE(CUSE); EVALUATE(CUSE);
EVALUATE(SRST); EVALUATE(SRST);
...@@ -931,6 +932,7 @@ class Simulator { ...@@ -931,6 +932,7 @@ class Simulator {
EVALUATE(ALGR); EVALUATE(ALGR);
EVALUATE(SLGR); EVALUATE(SLGR);
EVALUATE(MSGR); EVALUATE(MSGR);
EVALUATE(MSGRKC);
EVALUATE(DSGR); EVALUATE(DSGR);
EVALUATE(LRVGR); EVALUATE(LRVGR);
EVALUATE(LPGFR); EVALUATE(LPGFR);
......
...@@ -413,4 +413,89 @@ TEST(9) { ...@@ -413,4 +413,89 @@ TEST(9) {
} }
#endif #endif
// Test msrkc and msgrkc
TEST(10) {
if (!CpuFeatures::IsSupported(MISC_INSTR_EXT2)) {
return;
}
::printf("MISC_INSTR_EXT2 is enabled.\n");
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
Assembler assm(isolate, NULL, 0);
Label ok, failed;
{ // test 1: msrkc
__ lgfi(r2, Operand(3));
__ lgfi(r3, Operand(4));
__ msrkc(r1, r2, r3); // 3 * 4
__ b(static_cast<Condition>(le | overflow), &failed); // test failed.
__ chi(r1, Operand(12));
__ bne(&failed); // test failed.
__ lgfi(r2, Operand(-3));
__ lgfi(r3, Operand(4));
__ msrkc(r1, r2, r3); // -3 * 4
__ b(static_cast<Condition>(ge | overflow), &failed); // test failed.
__ chi(r1, Operand(-12));
__ bne(&failed); // test failed.
__ iilf(r2, Operand(0x80000000));
__ lgfi(r3, Operand(-1));
__ msrkc(r1, r2, r3); // INT_MIN * -1
__ b(nooverflow, &failed); // test failed.
__ cfi(r1, Operand(0x80000000));
__ bne(&failed); // test failed.
}
{ // test 1: msgrkc
__ lgfi(r2, Operand(3));
__ lgfi(r3, Operand(4));
__ msgrkc(r1, r2, r3); // 3 * 4
__ b(static_cast<Condition>(le | overflow), &failed); // test failed.
__ chi(r1, Operand(12));
__ bne(&failed); // test failed.
__ lgfi(r2, Operand(-3));
__ lgfi(r3, Operand(4));
__ msgrkc(r1, r2, r3); // -3 * 4
__ b(static_cast<Condition>(ge | overflow), &failed); // test failed.
__ chi(r1, Operand(-12));
__ bne(&failed); // test failed.
__ lgfi(r2, Operand::Zero());
__ iihf(r2, Operand(0x80000000));
__ lgfi(r3, Operand(-1));
__ msgrkc(r1, r2, r3); // INT_MIN * -1
__ b(nooverflow, &failed); // test failed.
__ cgr(r1, r2);
__ bne(&failed); // test failed.
}
__ bind(&ok);
__ lgfi(r2, Operand::Zero());
__ b(r14); // test done.
__ bind(&failed);
__ lgfi(r2, Operand(1));
__ b(r14);
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
code->Print();
#endif
F2 f = FUNCTION_CAST<F2>(code->entry());
intptr_t res = reinterpret_cast<intptr_t>(
CALL_GENERATED_CODE(isolate, f, 3, 4, 0, 0, 0));
::printf("f() = %" V8PRIxPTR "\n", res);
CHECK_EQ(0, static_cast<int>(res));
}
#undef __ #undef __
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