@@ -1420,64 +1420,20 @@ IRBuilderAsmJs::BuildStartCall(Js::OpCodeAsmJs newOpcode, uint32 offset)
14201420void
14211421IRBuilderAsmJs::InitializeMemAccessTypeInfo (Js::ArrayBufferView::ViewType viewType, _Out_ MemAccessTypeInfo * typeInfo)
14221422{
1423- typeInfo->type = TyInt32;
1424- typeInfo->valueRegType = WAsmJs::INT32;
1425-
1423+ AssertOrFailFast (typeInfo);
1424+
14261425 switch (viewType)
14271426 {
1428- case Js::ArrayBufferView::TYPE_INT8_TO_INT64:
1429- typeInfo->valueRegType = WAsmJs::INT64;
1430- case Js::ArrayBufferView::TYPE_INT8:
1431- typeInfo->arrayType = ValueType::GetObject (ObjectType::Int8Array);
1432- typeInfo->type = TyInt8;
1433- break ;
1434- case Js::ArrayBufferView::TYPE_UINT8_TO_INT64:
1435- typeInfo->valueRegType = WAsmJs::INT64;
1436- case Js::ArrayBufferView::TYPE_UINT8:
1437- typeInfo->arrayType = ValueType::GetObject (ObjectType::Uint8Array);
1438- typeInfo->type = TyUint8;
1439- break ;
1440- case Js::ArrayBufferView::TYPE_INT16_TO_INT64:
1441- typeInfo->valueRegType = WAsmJs::INT64;
1442- case Js::ArrayBufferView::TYPE_INT16:
1443- typeInfo->arrayType = ValueType::GetObject (ObjectType::Int16Array);
1444- typeInfo->type = TyInt16;
1445- break ;
1446- case Js::ArrayBufferView::TYPE_UINT16_TO_INT64:
1447- typeInfo->valueRegType = WAsmJs::INT64;
1448- case Js::ArrayBufferView::TYPE_UINT16:
1449- typeInfo->arrayType = ValueType::GetObject (ObjectType::Uint16Array);
1450- typeInfo->type = TyUint16;
1451- break ;
1452- case Js::ArrayBufferView::TYPE_INT32_TO_INT64:
1453- typeInfo->valueRegType = WAsmJs::INT64;
1454- case Js::ArrayBufferView::TYPE_INT32:
1455- typeInfo->arrayType = ValueType::GetObject (ObjectType::Int32Array);
1456- typeInfo->type = TyInt32;
1457- break ;
1458- case Js::ArrayBufferView::TYPE_UINT32_TO_INT64:
1459- typeInfo->valueRegType = WAsmJs::INT64;
1460- case Js::ArrayBufferView::TYPE_UINT32:
1461- typeInfo->arrayType = ValueType::GetObject (ObjectType::Uint32Array);
1462- typeInfo->type = TyUint32;
1463- break ;
1464- case Js::ArrayBufferView::TYPE_FLOAT32:
1465- typeInfo->valueRegType = WAsmJs::FLOAT32;
1466- typeInfo->arrayType = ValueType::GetObject (ObjectType::Float32Array);
1467- typeInfo->type = TyFloat32;
1468- break ;
1469- case Js::ArrayBufferView::TYPE_FLOAT64:
1470- typeInfo->valueRegType = WAsmJs::FLOAT64;
1471- typeInfo->arrayType = ValueType::GetObject (ObjectType::Float64Array);
1472- typeInfo->type = TyFloat64;
1473- break ;
1474- case Js::ArrayBufferView::TYPE_INT64:
1475- typeInfo->valueRegType = WAsmJs::INT64;
1476- typeInfo->arrayType = ValueType::GetObject (ObjectType::Int64Array);
1477- typeInfo->type = TyInt64;
1427+ #define ARRAYBUFFER_VIEW (name, align, RegType, MemType, irSuffix ) \
1428+ case Js::ArrayBufferView::TYPE_##name: \
1429+ typeInfo->valueRegType = WAsmJs::FromPrimitiveType<RegType>(); \
1430+ typeInfo->type = Ty##irSuffix;\
1431+ typeInfo->arrayType = ValueType::GetObject (ObjectType::##irSuffix##Array); \
1432+ Assert (TySize[Ty##irSuffix] == (1 <<align)); \
14781433 break ;
1434+ #include " Language/AsmJsArrayBufferViews.h"
14791435 default :
1480- Assume (UNREACHED);
1436+ AssertOrFailFast (UNREACHED);
14811437 }
14821438}
14831439
@@ -1493,11 +1449,15 @@ IRBuilderAsmJs::BuildWasmMemAccess(Js::OpCodeAsmJs newOpcode, uint32 offset)
14931449void
14941450IRBuilderAsmJs::BuildWasmMemAccess (Js::OpCodeAsmJs newOpcode, uint32 offset, uint32 slotIndex, Js::RegSlot value, uint32 constOffset, Js::ArrayBufferView::ViewType viewType)
14951451{
1496- bool isLd = newOpcode == Js::OpCodeAsmJs::LdArrWasm;
1497- Js::OpCode op = isLd ? Js::OpCode::LdArrViewElemWasm : Js::OpCode::StArrViewElem;
1452+ bool isAtomic = newOpcode == Js::OpCodeAsmJs::StArrAtomic || newOpcode == Js::OpCodeAsmJs::LdArrAtomic;
1453+ bool isLd = newOpcode == Js::OpCodeAsmJs::LdArrWasm || newOpcode == Js::OpCodeAsmJs::LdArrAtomic;
1454+ Js::OpCode op = isAtomic ?
1455+ isLd ? Js::OpCode::LdAtomicWasm : Js::OpCode::StAtomicWasm
1456+ : isLd ? Js::OpCode::LdArrViewElemWasm : Js::OpCode::StArrViewElem;
14981457
14991458 MemAccessTypeInfo typeInfo;
15001459 InitializeMemAccessTypeInfo (viewType, &typeInfo);
1460+ const uint32 memAccessSize = TySize[typeInfo.type ];
15011461
15021462 Js::RegSlot valueRegSlot = GetRegSlotFromTypedReg (value, typeInfo.valueRegType );
15031463 IR::Instr * instr = nullptr ;
@@ -1506,6 +1466,22 @@ IRBuilderAsmJs::BuildWasmMemAccess(Js::OpCodeAsmJs newOpcode, uint32 offset, uin
15061466
15071467 Js::RegSlot indexRegSlot = GetRegSlotFromIntReg (slotIndex);
15081468 IR::RegOpnd * indexOpnd = BuildSrcOpnd (indexRegSlot, TyUint32);
1469+ if (isAtomic && memAccessSize > 1 )
1470+ {
1471+ const uint32 mask = memAccessSize - 1 ;
1472+ // We need (constOffset + index) & mask == 0
1473+ // Since we know constOffset ahead of time
1474+ // what we need to check is index & mask == (memAccessSize - (constOffset & mask)) & mask
1475+ const uint32 offseted = constOffset & mask;
1476+ // In this IntContOpnd, the value is what the index&mask should be, the type carries the size of the access
1477+ IR::Opnd* offsetedOpnd = IR::IntConstOpnd::NewFromType ((memAccessSize - offseted) & mask, typeInfo.type , m_func);
1478+ IR::RegOpnd* intermediateIndex = IR::RegOpnd::New (TyUint32, m_func);
1479+ instr = IR::Instr::New (Js::OpCode::TrapIfUnalignedAccess, intermediateIndex, indexOpnd, offsetedOpnd, m_func);
1480+ AddInstr (instr, offset);
1481+
1482+ // Create dependency between load/store and trap through the index
1483+ indexOpnd = intermediateIndex;
1484+ }
15091485 indirOpnd = IR::IndirOpnd::New (BuildSrcOpnd (AsmJsRegSlots::BufferReg, TyVar), constOffset, typeInfo.type , m_func);
15101486 indirOpnd->SetIndexOpnd (indexOpnd);
15111487 indirOpnd->GetBaseOpnd ()->SetValueType (typeInfo.arrayType );
@@ -6877,36 +6853,12 @@ IRBuilderAsmJs::BuildAsmSimdTypedArr(Js::OpCodeAsmJs newOpcode, uint32 offset, u
68776853
68786854 switch (viewType)
68796855 {
6880- case Js::ArrayBufferView::TYPE_INT8:
6881- arrayType = ValueType::GetObject (ObjectType::Int8Array);
6882- break ;
6883- case Js::ArrayBufferView::TYPE_UINT8:
6884- arrayType = ValueType::GetObject (ObjectType::Uint8Array);
6885- break ;
6886- case Js::ArrayBufferView::TYPE_INT16:
6887- arrayType = ValueType::GetObject (ObjectType::Int16Array);
6888- mask = (uint32)~1 ;
6889- break ;
6890- case Js::ArrayBufferView::TYPE_UINT16:
6891- arrayType = ValueType::GetObject (ObjectType::Uint16Array);
6892- mask = (uint32)~1 ;
6893- break ;
6894- case Js::ArrayBufferView::TYPE_INT32:
6895- arrayType = ValueType::GetObject (ObjectType::Int32Array);
6896- mask = (uint32)~3 ;
6897- break ;
6898- case Js::ArrayBufferView::TYPE_UINT32:
6899- arrayType = ValueType::GetObject (ObjectType::Uint32Array);
6900- mask = (uint32)~3 ;
6901- break ;
6902- case Js::ArrayBufferView::TYPE_FLOAT32:
6903- arrayType = ValueType::GetObject (ObjectType::Float32Array);
6904- mask = (uint32)~3 ;
6905- break ;
6906- case Js::ArrayBufferView::TYPE_FLOAT64:
6907- arrayType = ValueType::GetObject (ObjectType::Float64Array);
6908- mask = (uint32)~7 ;
6856+ #define ARRAYBUFFER_VIEW (name, align, RegType, MemType, irSuffix ) \
6857+ case Js::ArrayBufferView::TYPE_##name: \
6858+ mask = ARRAYBUFFER_VIEW_MASK (align); \
6859+ arrayType = ValueType::GetObject (ObjectType::##irSuffix##Array); \
69096860 break ;
6861+ #include " Language/AsmJsArrayBufferViews.h"
69106862 default :
69116863 Assert (UNREACHED);
69126864 }
0 commit comments