Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 5.6k
Add BSF and BSR fallbacks for BitOperations methods#34550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
a5a0fc90569863412fe201a7708109e37e164ab5bd3f12a4194dee8469f60ab22b1500f17a5e05cc1bebdd6c846c7be460File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1028,6 +1028,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | ||
| void genHWIntrinsic_R_R_R_RM( | ||
| instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTree* op3); | ||
| void genBaseIntrinsic(GenTreeHWIntrinsic* node); | ||
| void genX86BaseIntrinsic(GenTreeHWIntrinsic* node); | ||
saucecontrol marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| void genSSEIntrinsic(GenTreeHWIntrinsic* node); | ||
| void genSSE2Intrinsic(GenTreeHWIntrinsic* node); | ||
| void genSSE41Intrinsic(GenTreeHWIntrinsic* node); | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -9448,7 +9448,8 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) | ||||||||||||||||||||
| // Use the large version if this is not a byte. This trick will not | ||||||||||||||||||||
| // work in case of SSE2 and AVX instructions. | ||||||||||||||||||||
| if ((size != EA_1BYTE) && (ins != INS_imul) && !IsSSEInstruction(ins) && !IsAVXInstruction(ins)) | ||||||||||||||||||||
| if ((size != EA_1BYTE) && (ins != INS_imul) && (ins != INS_bsf) && (ins != INS_bsr) && !IsSSEInstruction(ins) && | ||||||||||||||||||||
| !IsAVXInstruction(ins)) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| code++; | ||||||||||||||||||||
| } | ||||||||||||||||||||
| @@ -10214,8 +10215,9 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| // Use the large version if this is not a byte | ||||||||||||||||||||
| if ((size != EA_1BYTE) && (ins != INS_imul) && (!insIsCMOV(ins)) && !IsSSEInstruction(ins) && | ||||||||||||||||||||
| !IsAVXInstruction(ins)) | ||||||||||||||||||||
| // TODO-XArch-Cleanup Can the need for the 'w' size bit be encoded in the instruction flags? | ||||||||||||||||||||
| if ((size != EA_1BYTE) && (ins != INS_imul) && (ins != INS_bsf) && (ins != INS_bsr) && (!insIsCMOV(ins)) && | ||||||||||||||||||||
| !IsSSEInstruction(ins) && !IsAVXInstruction(ins)) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| code |= 0x1; | ||||||||||||||||||||
| } | ||||||||||||||||||||
| @@ -11248,7 +11250,8 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) | ||||||||||||||||||||
| #endif // TARGET_AMD64 | ||||||||||||||||||||
| } | ||||||||||||||||||||
| #ifdef FEATURE_HW_INTRINSICS | ||||||||||||||||||||
| else if ((ins == INS_crc32) || (ins == INS_lzcnt) || (ins == INS_popcnt) || (ins == INS_tzcnt)) | ||||||||||||||||||||
| else if ((ins == INS_bsf) || (ins == INS_bsr) || (ins == INS_crc32) || (ins == INS_lzcnt) || (ins == INS_popcnt) || | ||||||||||||||||||||
| (ins == INS_tzcnt)) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| code = insEncodeRMreg(ins, code); | ||||||||||||||||||||
| if ((ins == INS_crc32) && (size > EA_1BYTE)) | ||||||||||||||||||||
| @@ -14826,6 +14829,8 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins | ||||||||||||||||||||
| result.insLatency += PERFSCORE_LATENCY_2C; | ||||||||||||||||||||
| break; | ||||||||||||||||||||
| case INS_bsf: | ||||||||||||||||||||
| case INS_bsr: | ||||||||||||||||||||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice if we had a way to model Intel vs AMD here.
| ||||||||||||||||||||
| case INS_pextrb: | ||||||||||||||||||||
| case INS_pextrd: | ||||||||||||||||||||
| case INS_pextrw: | ||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -359,6 +359,10 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) | ||
| case InstructionSet_Vector256: | ||
| genBaseIntrinsic(node); | ||
| break; | ||
| case InstructionSet_X86Base: | ||
| case InstructionSet_X86Base_X64: | ||
| genX86BaseIntrinsic(node); | ||
| break; | ||
| case InstructionSet_SSE: | ||
| case InstructionSet_SSE_X64: | ||
| genSSEIntrinsic(node); | ||
| @@ -1249,6 +1253,40 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node) | ||
| genProduceReg(node); | ||
| } | ||
| //------------------------------------------------------------------------ | ||
| // genX86BaseIntrinsic: Generates the code for an X86 base hardware intrinsic node | ||
| // | ||
| // Arguments: | ||
| // node - The hardware intrinsic node | ||
| // | ||
| void CodeGen::genX86BaseIntrinsic(GenTreeHWIntrinsic* node) | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not needed for this PR, but we allowed | ||
| { | ||
| NamedIntrinsic intrinsicId = node->gtHWIntrinsicId; | ||
| switch (intrinsicId) | ||
| { | ||
| case NI_X86Base_BitScanForward: | ||
| case NI_X86Base_BitScanReverse: | ||
| case NI_X86Base_X64_BitScanForward: | ||
| case NI_X86Base_X64_BitScanReverse: | ||
| { | ||
| GenTree* op1 = node->gtGetOp1(); | ||
| regNumber targetReg = node->GetRegNum(); | ||
| var_types targetType = node->TypeGet(); | ||
| instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, targetType); | ||
| genConsumeOperands(node); | ||
| genHWIntrinsic_R_RM(node, ins, emitTypeSize(targetType), targetReg, op1); | ||
| genProduceReg(node); | ||
| break; | ||
| } | ||
| default: | ||
| unreached(); | ||
| break; | ||
| } | ||
| } | ||
| //------------------------------------------------------------------------ | ||
| // genSSEIntrinsic: Generates the code for an SSE hardware intrinsic node | ||
| // | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.