@@ -1421,64 +1421,20 @@ IRBuilderAsmJs::BuildStartCall(Js::OpCodeAsmJs newOpcode, uint32 offset)
14211421void
14221422IRBuilderAsmJs::InitializeMemAccessTypeInfo (Js::ArrayBufferView::ViewType viewType, _Out_ MemAccessTypeInfo * typeInfo)
14231423{
1424- typeInfo->type = TyInt32;
1425- typeInfo->valueRegType = WAsmJs::INT32;
1426-
1424+ AssertOrFailFast (typeInfo);
1425+
14271426 switch (viewType)
14281427 {
1429- case Js::ArrayBufferView::TYPE_INT8_TO_INT64:
1430- typeInfo->valueRegType = WAsmJs::INT64;
1431- case Js::ArrayBufferView::TYPE_INT8:
1432- typeInfo->arrayType = ValueType::GetObject (ObjectType::Int8Array);
1433- typeInfo->type = TyInt8;
1434- break ;
1435- case Js::ArrayBufferView::TYPE_UINT8_TO_INT64:
1436- typeInfo->valueRegType = WAsmJs::INT64;
1437- case Js::ArrayBufferView::TYPE_UINT8:
1438- typeInfo->arrayType = ValueType::GetObject (ObjectType::Uint8Array);
1439- typeInfo->type = TyUint8;
1440- break ;
1441- case Js::ArrayBufferView::TYPE_INT16_TO_INT64:
1442- typeInfo->valueRegType = WAsmJs::INT64;
1443- case Js::ArrayBufferView::TYPE_INT16:
1444- typeInfo->arrayType = ValueType::GetObject (ObjectType::Int16Array);
1445- typeInfo->type = TyInt16;
1446- break ;
1447- case Js::ArrayBufferView::TYPE_UINT16_TO_INT64:
1448- typeInfo->valueRegType = WAsmJs::INT64;
1449- case Js::ArrayBufferView::TYPE_UINT16:
1450- typeInfo->arrayType = ValueType::GetObject (ObjectType::Uint16Array);
1451- typeInfo->type = TyUint16;
1452- break ;
1453- case Js::ArrayBufferView::TYPE_INT32_TO_INT64:
1454- typeInfo->valueRegType = WAsmJs::INT64;
1455- case Js::ArrayBufferView::TYPE_INT32:
1456- typeInfo->arrayType = ValueType::GetObject (ObjectType::Int32Array);
1457- typeInfo->type = TyInt32;
1458- break ;
1459- case Js::ArrayBufferView::TYPE_UINT32_TO_INT64:
1460- typeInfo->valueRegType = WAsmJs::INT64;
1461- case Js::ArrayBufferView::TYPE_UINT32:
1462- typeInfo->arrayType = ValueType::GetObject (ObjectType::Uint32Array);
1463- typeInfo->type = TyUint32;
1464- break ;
1465- case Js::ArrayBufferView::TYPE_FLOAT32:
1466- typeInfo->valueRegType = WAsmJs::FLOAT32;
1467- typeInfo->arrayType = ValueType::GetObject (ObjectType::Float32Array);
1468- typeInfo->type = TyFloat32;
1469- break ;
1470- case Js::ArrayBufferView::TYPE_FLOAT64:
1471- typeInfo->valueRegType = WAsmJs::FLOAT64;
1472- typeInfo->arrayType = ValueType::GetObject (ObjectType::Float64Array);
1473- typeInfo->type = TyFloat64;
1474- break ;
1475- case Js::ArrayBufferView::TYPE_INT64:
1476- typeInfo->valueRegType = WAsmJs::INT64;
1477- typeInfo->arrayType = ValueType::GetObject (ObjectType::Int64Array);
1478- typeInfo->type = TyInt64;
1428+ #define ARRAYBUFFER_VIEW (name, align, RegType, MemType, irSuffix ) \
1429+ case Js::ArrayBufferView::TYPE_##name: \
1430+ typeInfo->valueRegType = WAsmJs::FromPrimitiveType<RegType>(); \
1431+ typeInfo->type = Ty##irSuffix;\
1432+ typeInfo->arrayType = ValueType::GetObject (ObjectType::##irSuffix##Array); \
1433+ Assert (TySize[Ty##irSuffix] == (1 <<align)); \
14791434 break ;
1435+ #include " Language/AsmJsArrayBufferViews.h"
14801436 default :
1481- Assume (UNREACHED);
1437+ AssertOrFailFast (UNREACHED);
14821438 }
14831439}
14841440
@@ -1494,11 +1450,15 @@ IRBuilderAsmJs::BuildWasmMemAccess(Js::OpCodeAsmJs newOpcode, uint32 offset)
14941450void
14951451IRBuilderAsmJs::BuildWasmMemAccess (Js::OpCodeAsmJs newOpcode, uint32 offset, uint32 slotIndex, Js::RegSlot value, uint32 constOffset, Js::ArrayBufferView::ViewType viewType)
14961452{
1497- bool isLd = newOpcode == Js::OpCodeAsmJs::LdArrWasm;
1498- Js::OpCode op = isLd ? Js::OpCode::LdArrViewElemWasm : Js::OpCode::StArrViewElem;
1453+ bool isAtomic = newOpcode == Js::OpCodeAsmJs::StArrAtomic || newOpcode == Js::OpCodeAsmJs::LdArrAtomic;
1454+ bool isLd = newOpcode == Js::OpCodeAsmJs::LdArrWasm || newOpcode == Js::OpCodeAsmJs::LdArrAtomic;
1455+ Js::OpCode op = isAtomic ?
1456+ isLd ? Js::OpCode::LdAtomicWasm : Js::OpCode::StAtomicWasm
1457+ : isLd ? Js::OpCode::LdArrViewElemWasm : Js::OpCode::StArrViewElem;
14991458
15001459 MemAccessTypeInfo typeInfo;
15011460 InitializeMemAccessTypeInfo (viewType, &typeInfo);
1461+ const uint32 memAccessSize = TySize[typeInfo.type ];
15021462
15031463 Js::RegSlot valueRegSlot = GetRegSlotFromTypedReg (value, typeInfo.valueRegType );
15041464 IR::Instr * instr = nullptr ;
@@ -1507,6 +1467,22 @@ IRBuilderAsmJs::BuildWasmMemAccess(Js::OpCodeAsmJs newOpcode, uint32 offset, uin
15071467
15081468 Js::RegSlot indexRegSlot = GetRegSlotFromIntReg (slotIndex);
15091469 IR::RegOpnd * indexOpnd = BuildSrcOpnd (indexRegSlot, TyUint32);
1470+ if (isAtomic && memAccessSize > 1 )
1471+ {
1472+ const uint32 mask = memAccessSize - 1 ;
1473+ // We need (constOffset + index) & mask == 0
1474+ // Since we know constOffset ahead of time
1475+ // what we need to check is index & mask == (memAccessSize - (constOffset & mask)) & mask
1476+ const uint32 offseted = constOffset & mask;
1477+ // In this IntContOpnd, the value is what the index&mask should be, the type carries the size of the access
1478+ IR::Opnd* offsetedOpnd = IR::IntConstOpnd::NewFromType ((memAccessSize - offseted) & mask, typeInfo.type , m_func);
1479+ IR::RegOpnd* intermediateIndex = IR::RegOpnd::New (TyUint32, m_func);
1480+ instr = IR::Instr::New (Js::OpCode::TrapIfUnalignedAccess, intermediateIndex, indexOpnd, offsetedOpnd, m_func);
1481+ AddInstr (instr, offset);
1482+
1483+ // Create dependency between load/store and trap through the index
1484+ indexOpnd = intermediateIndex;
1485+ }
15101486 indirOpnd = IR::IndirOpnd::New (BuildSrcOpnd (AsmJsRegSlots::BufferReg, TyVar), constOffset, typeInfo.type , m_func);
15111487 indirOpnd->SetIndexOpnd (indexOpnd);
15121488 indirOpnd->GetBaseOpnd ()->SetValueType (typeInfo.arrayType );
@@ -6915,36 +6891,12 @@ IRBuilderAsmJs::BuildAsmSimdTypedArr(Js::OpCodeAsmJs newOpcode, uint32 offset, u
69156891
69166892 switch (viewType)
69176893 {
6918- case Js::ArrayBufferView::TYPE_INT8:
6919- arrayType = ValueType::GetObject (ObjectType::Int8Array);
6920- break ;
6921- case Js::ArrayBufferView::TYPE_UINT8:
6922- arrayType = ValueType::GetObject (ObjectType::Uint8Array);
6923- break ;
6924- case Js::ArrayBufferView::TYPE_INT16:
6925- arrayType = ValueType::GetObject (ObjectType::Int16Array);
6926- mask = (uint32)~1 ;
6927- break ;
6928- case Js::ArrayBufferView::TYPE_UINT16:
6929- arrayType = ValueType::GetObject (ObjectType::Uint16Array);
6930- mask = (uint32)~1 ;
6931- break ;
6932- case Js::ArrayBufferView::TYPE_INT32:
6933- arrayType = ValueType::GetObject (ObjectType::Int32Array);
6934- mask = (uint32)~3 ;
6935- break ;
6936- case Js::ArrayBufferView::TYPE_UINT32:
6937- arrayType = ValueType::GetObject (ObjectType::Uint32Array);
6938- mask = (uint32)~3 ;
6939- break ;
6940- case Js::ArrayBufferView::TYPE_FLOAT32:
6941- arrayType = ValueType::GetObject (ObjectType::Float32Array);
6942- mask = (uint32)~3 ;
6943- break ;
6944- case Js::ArrayBufferView::TYPE_FLOAT64:
6945- arrayType = ValueType::GetObject (ObjectType::Float64Array);
6946- mask = (uint32)~7 ;
6894+ #define ARRAYBUFFER_VIEW (name, align, RegType, MemType, irSuffix ) \
6895+ case Js::ArrayBufferView::TYPE_##name: \
6896+ mask = ARRAYBUFFER_VIEW_MASK (align); \
6897+ arrayType = ValueType::GetObject (ObjectType::##irSuffix##Array); \
69476898 break ;
6899+ #include " Language/AsmJsArrayBufferViews.h"
69486900 default :
69496901 Assert (UNREACHED);
69506902 }
0 commit comments