Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Unified Diff: src/WasmTranslator.cpp

Issue 1900213002: Subzero - WASM: Codegen fixes, better test infrastructure (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Copyright notice and TODO Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« runtime/wasm-runtime.cpp ('K') | « runtime/wasm-runtime.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/WasmTranslator.cpp
diff --git a/src/WasmTranslator.cpp b/src/WasmTranslator.cpp
index 7c462d9b1b06c1de46c4150b8a4fe8ae4858281b..14b0607cac63ad5bc5e8555c103f8ca9163f9a40 100644
--- a/src/WasmTranslator.cpp
+++ b/src/WasmTranslator.cpp
@@ -229,10 +229,18 @@ bool isComparison(wasm::WasmOpcode Opcode) {
case kExprI64GtS:
case kExprI32GtU:
case kExprI64GtU:
+ case kExprF32Eq:
+ case kExprF64Eq:
case kExprF32Ne:
case kExprF64Ne:
case kExprF32Le:
case kExprF64Le:
+ case kExprF32Lt:
+ case kExprF64Lt:
+ case kExprF32Ge:
+ case kExprF64Ge:
+ case kExprF32Gt:
+ case kExprF64Gt:
case kExprI32LeS:
case kExprI64LeS:
case kExprI32GeU:
@@ -324,7 +332,7 @@ public:
// TODO(eholk): find a better way besides multiplying by some arbitrary
// constant.
- auto *Phi = InstPhi::create(Func, Count * 10, Dest);
+ auto *Phi = InstPhi::create(Func, Count * 200, Dest);
for (uint32_t i = 0; i < Count; ++i) {
auto *Op = Vals[i].toOperand();
assert(Op);
@@ -393,16 +401,36 @@ public:
Control()->appendInst(
InstArithmetic::create(Func, InstArithmetic::Sub, Dest, Left, Right));
break;
+ case kExprF32Sub:
+ case kExprF64Sub:
+ Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fsub,
+ Dest, Left, Right));
+ break;
case kExprI32Mul:
case kExprI64Mul:
Control()->appendInst(
InstArithmetic::create(Func, InstArithmetic::Mul, Dest, Left, Right));
break;
+ case kExprF32Mul:
+ case kExprF64Mul:
+ Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fmul,
+ Dest, Left, Right));
+ break;
+ case kExprI32DivS:
+ case kExprI64DivS:
+ Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Sdiv,
+ Dest, Left, Right));
+ break;
case kExprI32DivU:
case kExprI64DivU:
Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Udiv,
Dest, Left, Right));
break;
+ case kExprF32Div:
+ case kExprF64Div:
+ Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fdiv,
+ Dest, Left, Right));
+ break;
case kExprI32RemU:
case kExprI64RemU:
Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Urem,
@@ -428,30 +456,63 @@ public:
Control()->appendInst(
InstArithmetic::create(Func, InstArithmetic::Shl, Dest, Left, Right));
break;
- case kExprI32Rol: {
+ case kExprI32Rol:
+ case kExprI64Rol: {
// TODO(eholk): add rotate as an ICE instruction to make it easier to take
// advantage of hardware support.
- // TODO(eholk): don't hardcode so many numbers.
- auto *Masked = makeVariable(IceType_i32);
- auto *Bottom = makeVariable(IceType_i32);
- auto *Top = makeVariable(IceType_i32);
- Control()->appendInst(InstArithmetic::create(
- Func, InstArithmetic::And, Masked, Right, Ctx->getConstantInt32(31)));
+ const auto DestTy = Left.toOperand()->getType();
+ const SizeT BitCount = typeWidthInBytes(DestTy) * 8;
+
+ auto *Masked = makeVariable(DestTy);
+ auto *Bottom = makeVariable(DestTy);
+ auto *Top = makeVariable(DestTy);
+ Control()->appendInst(
+ InstArithmetic::create(Func, InstArithmetic::And, Masked, Right,
+ Ctx->getConstantInt(DestTy, BitCount - 1)));
Control()->appendInst(
InstArithmetic::create(Func, InstArithmetic::Shl, Top, Left, Masked));
- auto *RotShift = makeVariable(IceType_i32);
+ auto *RotShift = makeVariable(DestTy);
+ Control()->appendInst(InstArithmetic::create(
+ Func, InstArithmetic::Sub, RotShift,
+ Ctx->getConstantInt(DestTy, BitCount), Masked));
+ Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr,
+ Bottom, Left, RotShift));
+ Control()->appendInst(
+ InstArithmetic::create(Func, InstArithmetic::Or, Dest, Top, Bottom));
+ break;
+ }
+ case kExprI32Ror:
+ case kExprI64Ror: {
+ // TODO(eholk): add rotate as an ICE instruction to make it easier to take
+ // advantage of hardware support.
+
+ const auto DestTy = Left.toOperand()->getType();
+ const SizeT BitCount = typeWidthInBytes(DestTy) * 8;
+
+ auto *Masked = makeVariable(DestTy);
+ auto *Bottom = makeVariable(DestTy);
+ auto *Top = makeVariable(DestTy);
Control()->appendInst(
- InstArithmetic::create(Func, InstArithmetic::Sub, RotShift,
- Ctx->getConstantInt32(32), Masked));
+ InstArithmetic::create(Func, InstArithmetic::And, Masked, Right,
+ Ctx->getConstantInt(DestTy, BitCount - 1)));
Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr,
- Bottom, Left, Masked));
+ Top, Left, Masked));
+ auto *RotShift = makeVariable(DestTy);
+ Control()->appendInst(InstArithmetic::create(
+ Func, InstArithmetic::Sub, RotShift,
+ Ctx->getConstantInt(DestTy, BitCount), Masked));
+ Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Shl,
+ Bottom, Left, RotShift));
Control()->appendInst(
InstArithmetic::create(Func, InstArithmetic::Or, Dest, Top, Bottom));
break;
}
case kExprI32ShrU:
case kExprI64ShrU:
+ Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr,
+ Dest, Left, Right));
+ break;
case kExprI32ShrS:
case kExprI64ShrS:
Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Ashr,
@@ -532,6 +593,7 @@ public:
InstIcmp::create(Func, InstIcmp::Sge, TmpDest, Left, Right));
Control()->appendInst(
InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
+ break;
}
case kExprI32GtS:
case kExprI64GtS: {
@@ -551,6 +613,15 @@ public:
InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break;
}
+ case kExprF32Eq:
+ case kExprF64Eq: {
+ auto *TmpDest = makeVariable(IceType_i1);
+ Control()->appendInst(
+ InstFcmp::create(Func, InstFcmp::Ueq, TmpDest, Left, Right));
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
+ break;
+ }
case kExprF32Ne:
case kExprF64Ne: {
auto *TmpDest = makeVariable(IceType_i1);
@@ -569,6 +640,33 @@ public:
InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break;
}
+ case kExprF32Lt:
+ case kExprF64Lt: {
+ auto *TmpDest = makeVariable(IceType_i1);
+ Control()->appendInst(
+ InstFcmp::create(Func, InstFcmp::Ult, TmpDest, Left, Right));
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
+ break;
+ }
+ case kExprF32Ge:
+ case kExprF64Ge: {
+ auto *TmpDest = makeVariable(IceType_i1);
+ Control()->appendInst(
+ InstFcmp::create(Func, InstFcmp::Uge, TmpDest, Left, Right));
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
+ break;
+ }
+ case kExprF32Gt:
+ case kExprF64Gt: {
+ auto *TmpDest = makeVariable(IceType_i1);
+ Control()->appendInst(
+ InstFcmp::create(Func, InstFcmp::Ugt, TmpDest, Left, Right));
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
+ break;
+ }
default:
LOG(out << "Unknown binop: " << WasmOpcodes::OpcodeName(Opcode) << "\n");
llvm::report_fatal_error("Uncovered or invalid binop.");
@@ -598,6 +696,20 @@ public:
Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp));
break;
}
+ case kExprI32Ctz: {
+ Dest = makeVariable(IceType_i32);
+ const auto FnName = Ctx->getGlobalString("llvm.cttz.i32");
+ bool BadInstrinsic = false;
+ const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic);
+ assert(!BadInstrinsic);
+ assert(Info);
+
+ auto *Call = InstIntrinsicCall::create(
+ Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info);
+ Call->addArg(Input);
+ Control()->appendInst(Call);
+ break;
+ }
case kExprF32Neg: {
Dest = makeVariable(IceType_f32);
Control()->appendInst(InstArithmetic::create(
@@ -610,6 +722,56 @@ public:
Func, InstArithmetic::Fsub, Dest, Ctx->getConstantDouble(0), Input));
break;
}
+ case kExprF32Abs: {
+ Dest = makeVariable(IceType_f32);
+ const auto FnName = Ctx->getGlobalString("llvm.fabs.f32");
+ bool BadInstrinsic = false;
+ const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic);
+ assert(!BadInstrinsic);
+ assert(Info);
+
+ auto *Call = InstIntrinsicCall::create(
+ Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info);
+ Call->addArg(Input);
+ Control()->appendInst(Call);
+ break;
+ }
+ case kExprF64Abs: {
+ Dest = makeVariable(IceType_f64);
+ const auto FnName = Ctx->getGlobalString("llvm.fabs.f64");
+ bool BadInstrinsic = false;
+ const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic);
+ assert(!BadInstrinsic);
+ assert(Info);
+
+ auto *Call = InstIntrinsicCall::create(
+ Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info);
+ Call->addArg(Input);
+ Control()->appendInst(Call);
+ break;
+ }
+ case kExprF32Floor: {
+ Dest = makeVariable(IceType_f64);
+ const auto FnName = Ctx->getGlobalString("_ZN3env5floorEf");
+ constexpr bool HasTailCall = false;
+
+ auto *Call = InstCall::create(
+ Func, 1, Dest, Ctx->getConstantExternSym(FnName), HasTailCall);
+ Call->addArg(Input);
+ Control()->appendInst(Call);
+ break;
+ }
+ case kExprF64Floor: {
+ Dest = makeVariable(IceType_f64);
+ const auto FnName = Ctx->getGlobalString("_ZN3env5floorEd");
+ constexpr bool HasTailCall = false;
+
+ auto *Call = InstCall::create(
+ Func, 1, Dest, Ctx->getConstantExternSym(FnName), HasTailCall);
+ Call->addArg(Input);
+ Control()->appendInst(Call);
+ break;
+ }
case kExprI64UConvertI32:
Dest = makeVariable(IceType_i64);
Control()->appendInst(
@@ -620,6 +782,41 @@ public:
Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, Input));
break;
+ case kExprI32SConvertF32:
+ Dest = makeVariable(IceType_i32);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Fptosi, Dest, Input));
+ break;
+ case kExprI32UConvertF32:
+ Dest = makeVariable(IceType_i32);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Fptoui, Dest, Input));
+ break;
+ case kExprI32SConvertF64:
+ Dest = makeVariable(IceType_i32);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Fptosi, Dest, Input));
+ break;
+ case kExprI32UConvertF64:
+ Dest = makeVariable(IceType_i32);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Fptoui, Dest, Input));
+ break;
+ case kExprI32ReinterpretF32:
+ Dest = makeVariable(IceType_i32);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Bitcast, Dest, Input));
+ break;
+ case kExprI64ReinterpretF64:
+ Dest = makeVariable(IceType_i64);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Bitcast, Dest, Input));
+ break;
+ case kExprF64ReinterpretI64:
+ Dest = makeVariable(IceType_f64);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Bitcast, Dest, Input));
+ break;
case kExprI32ConvertI64:
Dest = makeVariable(IceType_i32);
Control()->appendInst(
@@ -630,6 +827,36 @@ public:
Control()->appendInst(
InstCast::create(Func, InstCast::Sitofp, Dest, Input));
break;
+ case kExprF64UConvertI32:
+ Dest = makeVariable(IceType_f64);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Uitofp, Dest, Input));
+ break;
+ case kExprF64ConvertF32:
+ Dest = makeVariable(IceType_f64);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Fpext, Dest, Input));
+ break;
+ case kExprF32SConvertI32:
+ Dest = makeVariable(IceType_f32);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Sitofp, Dest, Input));
+ break;
+ case kExprF32UConvertI32:
+ Dest = makeVariable(IceType_f32);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Uitofp, Dest, Input));
+ break;
+ case kExprF32ReinterpretI32:
+ Dest = makeVariable(IceType_f32);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Bitcast, Dest, Input));
+ break;
+ case kExprF32ConvertF64:
+ Dest = makeVariable(IceType_f32);
+ Control()->appendInst(
+ InstCast::create(Func, InstCast::Fptrunc, Dest, Input));
+ break;
default:
LOG(out << "Unknown unop: " << WasmOpcodes::OpcodeName(Opcode) << "\n");
llvm::report_fatal_error("Uncovered or invalid unop.");
@@ -953,7 +1180,8 @@ public:
Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index,
uint32_t Offset) {
- LOG(out << "LoadMem(" << Index << "[" << Offset << "]) = ");
+ LOG(out << "LoadMem." << toIceType(MemType) << "(" << Index << "[" << Offset
+ << "]) = ");
auto *RealAddr = sanitizeAddress(Index, Offset);
@@ -988,7 +1216,8 @@ public:
return OperandNode(Result);
}
void StoreMem(MachineType Type, Node Index, uint32_t Offset, Node Val) {
- LOG(out << "StoreMem(" << Index << "[" << Offset << "] = " << Val << ")"
+ LOG(out << "StoreMem." << toIceType(Type) << "(" << Index << "[" << Offset
+ << "] = " << Val << ")"
<< "\n");
auto *RealAddr = sanitizeAddress(Index, Offset);
@@ -1101,11 +1330,13 @@ std::unique_ptr<Cfg> WasmTranslator::translateFunction(Zone *Zone,
return Func;
}
+// TODO(eholk): compute the correct buffer size. This uses 256k by default,
+// which has been big enough for testing but is not a general solution.
+constexpr SizeT BUFFER_SIZE = 256 << 10;
+
WasmTranslator::WasmTranslator(GlobalContext *Ctx)
- : Translator(Ctx), Buffer(new uint8_t[24 << 10]), BufferSize(24 << 10) {
- // TODO(eholk): compute the correct buffer size. This uses 24k by default,
- // which has been big enough for testing but is not a general solution.
-}
+ : Translator(Ctx), Buffer(new uint8_t[BUFFER_SIZE]),
+ BufferSize(BUFFER_SIZE) {}
void WasmTranslator::translate(
const std::string &IRFilename,
@@ -1118,6 +1349,7 @@ void WasmTranslator::translate(
SizeT BytesRead = InputStream->GetBytes(Buffer.get(), BufferSize);
LOG(out << "Read " << BytesRead << " bytes"
<< "\n");
+ assert(BytesRead < BufferSize);
LOG(out << "Decoding module " << IRFilename << "\n");
« runtime/wasm-runtime.cpp ('K') | « runtime/wasm-runtime.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698