4592 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=thumbv7m-eabi %s -o - | FileCheck %s --check-prefix V7M3; RUN: llc -mtriple=armv7a-eabi %s -o - | FileCheck %s --check-prefix V7A4; RUN: llc -mtriple=thumbv7a-eabi %s -o - | FileCheck %s --check-prefix V7A-T5; RUN: llc -mtriple=armv6m-eabi %s -o - | FileCheck %s --check-prefix V6M6 7; Patterns:8; a) (x >> start) & (1 << nbits) - 19; b) (x >> start) & ~(-1 << nbits)10; c) (x >> start) & (-1 >> (32 - y))11; d) (x >> start) << (32 - y) >> (32 - y)12; are equivalent.13 14; ---------------------------------------------------------------------------- ;15; Pattern a. 32-bit16; ---------------------------------------------------------------------------- ;17 18define i32 @bextr32_a0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {19; V7M-LABEL: bextr32_a0:20; V7M: @ %bb.0:21; V7M-NEXT: lsrs r0, r122; V7M-NEXT: movs r1, #123; V7M-NEXT: lsls r1, r224; V7M-NEXT: subs r1, #125; V7M-NEXT: ands r0, r126; V7M-NEXT: bx lr27;28; V7A-LABEL: bextr32_a0:29; V7A: @ %bb.0:30; V7A-NEXT: mov r12, #131; V7A-NEXT: mvn r3, #032; V7A-NEXT: add r2, r3, r12, lsl r233; V7A-NEXT: and r0, r2, r0, lsr r134; V7A-NEXT: bx lr35;36; V7A-T-LABEL: bextr32_a0:37; V7A-T: @ %bb.0:38; V7A-T-NEXT: lsrs r0, r139; V7A-T-NEXT: movs r1, #140; V7A-T-NEXT: lsls r1, r241; V7A-T-NEXT: subs r1, #142; V7A-T-NEXT: ands r0, r143; V7A-T-NEXT: bx lr44;45; V6M-LABEL: bextr32_a0:46; V6M: @ %bb.0:47; V6M-NEXT: lsrs r0, r148; V6M-NEXT: movs r1, #149; V6M-NEXT: lsls r1, r250; V6M-NEXT: subs r1, r1, #151; V6M-NEXT: ands r0, r152; V6M-NEXT: bx lr53 %shifted = lshr i32 %val, %numskipbits54 %onebit = shl i32 1, %numlowbits55 %mask = add nsw i32 %onebit, -156 %masked = and i32 %mask, %shifted57 ret i32 %masked58}59 60define i32 @bextr32_a0_arithmetic(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {61; V7M-LABEL: bextr32_a0_arithmetic:62; V7M: @ %bb.0:63; V7M-NEXT: asrs r0, r164; V7M-NEXT: movs r1, #165; V7M-NEXT: lsls r1, r266; V7M-NEXT: subs r1, #167; V7M-NEXT: ands r0, r168; V7M-NEXT: bx lr69;70; V7A-LABEL: bextr32_a0_arithmetic:71; V7A: @ %bb.0:72; V7A-NEXT: mov r12, #173; V7A-NEXT: mvn r3, #074; V7A-NEXT: add r2, r3, r12, lsl r275; V7A-NEXT: and r0, r2, r0, asr r176; V7A-NEXT: bx lr77;78; V7A-T-LABEL: bextr32_a0_arithmetic:79; V7A-T: @ %bb.0:80; V7A-T-NEXT: asrs r0, r181; V7A-T-NEXT: movs r1, #182; V7A-T-NEXT: lsls r1, r283; V7A-T-NEXT: subs r1, #184; V7A-T-NEXT: ands r0, r185; V7A-T-NEXT: bx lr86;87; V6M-LABEL: bextr32_a0_arithmetic:88; V6M: @ %bb.0:89; V6M-NEXT: asrs r0, r190; V6M-NEXT: movs r1, #191; V6M-NEXT: lsls r1, r292; V6M-NEXT: subs r1, r1, #193; V6M-NEXT: ands r0, r194; V6M-NEXT: bx lr95 %shifted = ashr i32 %val, %numskipbits96 %onebit = shl i32 1, %numlowbits97 %mask = add nsw i32 %onebit, -198 %masked = and i32 %mask, %shifted99 ret i32 %masked100}101 102define i32 @bextr32_a1_indexzext(i32 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {103; V7M-LABEL: bextr32_a1_indexzext:104; V7M: @ %bb.0:105; V7M-NEXT: lsrs r0, r1106; V7M-NEXT: movs r1, #1107; V7M-NEXT: lsls r1, r2108; V7M-NEXT: subs r1, #1109; V7M-NEXT: ands r0, r1110; V7M-NEXT: bx lr111;112; V7A-LABEL: bextr32_a1_indexzext:113; V7A: @ %bb.0:114; V7A-NEXT: mov r12, #1115; V7A-NEXT: mvn r3, #0116; V7A-NEXT: add r2, r3, r12, lsl r2117; V7A-NEXT: and r0, r2, r0, lsr r1118; V7A-NEXT: bx lr119;120; V7A-T-LABEL: bextr32_a1_indexzext:121; V7A-T: @ %bb.0:122; V7A-T-NEXT: lsrs r0, r1123; V7A-T-NEXT: movs r1, #1124; V7A-T-NEXT: lsls r1, r2125; V7A-T-NEXT: subs r1, #1126; V7A-T-NEXT: ands r0, r1127; V7A-T-NEXT: bx lr128;129; V6M-LABEL: bextr32_a1_indexzext:130; V6M: @ %bb.0:131; V6M-NEXT: lsrs r0, r1132; V6M-NEXT: movs r1, #1133; V6M-NEXT: lsls r1, r2134; V6M-NEXT: subs r1, r1, #1135; V6M-NEXT: ands r0, r1136; V6M-NEXT: bx lr137 %skip = zext i8 %numskipbits to i32138 %shifted = lshr i32 %val, %skip139 %conv = zext i8 %numlowbits to i32140 %onebit = shl i32 1, %conv141 %mask = add nsw i32 %onebit, -1142 %masked = and i32 %mask, %shifted143 ret i32 %masked144}145 146define i32 @bextr32_a2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {147; V7M-LABEL: bextr32_a2_load:148; V7M: @ %bb.0:149; V7M-NEXT: ldr r0, [r0]150; V7M-NEXT: lsrs r0, r1151; V7M-NEXT: movs r1, #1152; V7M-NEXT: lsls r1, r2153; V7M-NEXT: subs r1, #1154; V7M-NEXT: ands r0, r1155; V7M-NEXT: bx lr156;157; V7A-LABEL: bextr32_a2_load:158; V7A: @ %bb.0:159; V7A-NEXT: ldr r0, [r0]160; V7A-NEXT: mov r12, #1161; V7A-NEXT: mvn r3, #0162; V7A-NEXT: add r2, r3, r12, lsl r2163; V7A-NEXT: and r0, r2, r0, lsr r1164; V7A-NEXT: bx lr165;166; V7A-T-LABEL: bextr32_a2_load:167; V7A-T: @ %bb.0:168; V7A-T-NEXT: ldr r0, [r0]169; V7A-T-NEXT: lsrs r0, r1170; V7A-T-NEXT: movs r1, #1171; V7A-T-NEXT: lsls r1, r2172; V7A-T-NEXT: subs r1, #1173; V7A-T-NEXT: ands r0, r1174; V7A-T-NEXT: bx lr175;176; V6M-LABEL: bextr32_a2_load:177; V6M: @ %bb.0:178; V6M-NEXT: ldr r3, [r0]179; V6M-NEXT: lsrs r3, r1180; V6M-NEXT: movs r0, #1181; V6M-NEXT: lsls r0, r2182; V6M-NEXT: subs r0, r0, #1183; V6M-NEXT: ands r0, r3184; V6M-NEXT: bx lr185 %val = load i32, ptr %w186 %shifted = lshr i32 %val, %numskipbits187 %onebit = shl i32 1, %numlowbits188 %mask = add nsw i32 %onebit, -1189 %masked = and i32 %mask, %shifted190 ret i32 %masked191}192 193define i32 @bextr32_a3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {194; V7M-LABEL: bextr32_a3_load_indexzext:195; V7M: @ %bb.0:196; V7M-NEXT: ldr r0, [r0]197; V7M-NEXT: lsrs r0, r1198; V7M-NEXT: movs r1, #1199; V7M-NEXT: lsls r1, r2200; V7M-NEXT: subs r1, #1201; V7M-NEXT: ands r0, r1202; V7M-NEXT: bx lr203;204; V7A-LABEL: bextr32_a3_load_indexzext:205; V7A: @ %bb.0:206; V7A-NEXT: ldr r0, [r0]207; V7A-NEXT: mov r12, #1208; V7A-NEXT: mvn r3, #0209; V7A-NEXT: add r2, r3, r12, lsl r2210; V7A-NEXT: and r0, r2, r0, lsr r1211; V7A-NEXT: bx lr212;213; V7A-T-LABEL: bextr32_a3_load_indexzext:214; V7A-T: @ %bb.0:215; V7A-T-NEXT: ldr r0, [r0]216; V7A-T-NEXT: lsrs r0, r1217; V7A-T-NEXT: movs r1, #1218; V7A-T-NEXT: lsls r1, r2219; V7A-T-NEXT: subs r1, #1220; V7A-T-NEXT: ands r0, r1221; V7A-T-NEXT: bx lr222;223; V6M-LABEL: bextr32_a3_load_indexzext:224; V6M: @ %bb.0:225; V6M-NEXT: ldr r3, [r0]226; V6M-NEXT: lsrs r3, r1227; V6M-NEXT: movs r0, #1228; V6M-NEXT: lsls r0, r2229; V6M-NEXT: subs r0, r0, #1230; V6M-NEXT: ands r0, r3231; V6M-NEXT: bx lr232 %val = load i32, ptr %w233 %skip = zext i8 %numskipbits to i32234 %shifted = lshr i32 %val, %skip235 %conv = zext i8 %numlowbits to i32236 %onebit = shl i32 1, %conv237 %mask = add nsw i32 %onebit, -1238 %masked = and i32 %mask, %shifted239 ret i32 %masked240}241 242define i32 @bextr32_a4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {243; V7M-LABEL: bextr32_a4_commutative:244; V7M: @ %bb.0:245; V7M-NEXT: lsrs r0, r1246; V7M-NEXT: movs r1, #1247; V7M-NEXT: lsls r1, r2248; V7M-NEXT: subs r1, #1249; V7M-NEXT: ands r0, r1250; V7M-NEXT: bx lr251;252; V7A-LABEL: bextr32_a4_commutative:253; V7A: @ %bb.0:254; V7A-NEXT: mov r12, #1255; V7A-NEXT: mvn r3, #0256; V7A-NEXT: add r2, r3, r12, lsl r2257; V7A-NEXT: and r0, r2, r0, lsr r1258; V7A-NEXT: bx lr259;260; V7A-T-LABEL: bextr32_a4_commutative:261; V7A-T: @ %bb.0:262; V7A-T-NEXT: lsrs r0, r1263; V7A-T-NEXT: movs r1, #1264; V7A-T-NEXT: lsls r1, r2265; V7A-T-NEXT: subs r1, #1266; V7A-T-NEXT: ands r0, r1267; V7A-T-NEXT: bx lr268;269; V6M-LABEL: bextr32_a4_commutative:270; V6M: @ %bb.0:271; V6M-NEXT: lsrs r0, r1272; V6M-NEXT: movs r1, #1273; V6M-NEXT: lsls r1, r2274; V6M-NEXT: subs r1, r1, #1275; V6M-NEXT: ands r0, r1276; V6M-NEXT: bx lr277 %shifted = lshr i32 %val, %numskipbits278 %onebit = shl i32 1, %numlowbits279 %mask = add nsw i32 %onebit, -1280 %masked = and i32 %shifted, %mask ; swapped order281 ret i32 %masked282}283 284; 64-bit285 286define i64 @bextr64_a0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {287; V7M-LABEL: bextr64_a0:288; V7M: @ %bb.0:289; V7M-NEXT: .save {r4, lr}290; V7M-NEXT: push {r4, lr}291; V7M-NEXT: ldr.w r12, [sp, #8]292; V7M-NEXT: mov.w lr, #1293; V7M-NEXT: lsrs r0, r2294; V7M-NEXT: rsb.w r4, r12, #32295; V7M-NEXT: subs.w r3, r12, #32296; V7M-NEXT: lsr.w r4, lr, r4297; V7M-NEXT: it pl298; V7M-NEXT: lslpl.w r4, lr, r3299; V7M-NEXT: lsl.w r3, lr, r12300; V7M-NEXT: it pl301; V7M-NEXT: movpl r3, #0302; V7M-NEXT: subs r3, #1303; V7M-NEXT: sbc r12, r4, #0304; V7M-NEXT: rsb.w r4, r2, #32305; V7M-NEXT: lsl.w r4, r1, r4306; V7M-NEXT: orrs r0, r4307; V7M-NEXT: subs.w r4, r2, #32308; V7M-NEXT: it pl309; V7M-NEXT: lsrpl.w r0, r1, r4310; V7M-NEXT: lsr.w r1, r1, r2311; V7M-NEXT: and.w r0, r0, r3312; V7M-NEXT: it pl313; V7M-NEXT: movpl r1, #0314; V7M-NEXT: and.w r1, r1, r12315; V7M-NEXT: pop {r4, pc}316;317; V7A-LABEL: bextr64_a0:318; V7A: @ %bb.0:319; V7A-NEXT: .save {r4, r5, r11, lr}320; V7A-NEXT: push {r4, r5, r11, lr}321; V7A-NEXT: ldr lr, [sp, #16]322; V7A-NEXT: mov r5, #1323; V7A-NEXT: lsr r0, r0, r2324; V7A-NEXT: rsb r12, lr, #32325; V7A-NEXT: subs r4, lr, #32326; V7A-NEXT: lsr r3, r5, r12327; V7A-NEXT: lslpl r3, r5, r4328; V7A-NEXT: lsl r5, r5, lr329; V7A-NEXT: movwpl r5, #0330; V7A-NEXT: rsb r4, r2, #32331; V7A-NEXT: subs r5, r5, #1332; V7A-NEXT: sbc r3, r3, #0333; V7A-NEXT: orr r0, r0, r1, lsl r4334; V7A-NEXT: subs r4, r2, #32335; V7A-NEXT: lsrpl r0, r1, r4336; V7A-NEXT: lsr r1, r1, r2337; V7A-NEXT: movwpl r1, #0338; V7A-NEXT: and r0, r5, r0339; V7A-NEXT: and r1, r3, r1340; V7A-NEXT: pop {r4, r5, r11, pc}341;342; V7A-T-LABEL: bextr64_a0:343; V7A-T: @ %bb.0:344; V7A-T-NEXT: .save {r4, lr}345; V7A-T-NEXT: push {r4, lr}346; V7A-T-NEXT: ldr.w r12, [sp, #8]347; V7A-T-NEXT: mov.w lr, #1348; V7A-T-NEXT: lsrs r0, r2349; V7A-T-NEXT: rsb.w r4, r12, #32350; V7A-T-NEXT: subs.w r3, r12, #32351; V7A-T-NEXT: lsr.w r4, lr, r4352; V7A-T-NEXT: it pl353; V7A-T-NEXT: lslpl.w r4, lr, r3354; V7A-T-NEXT: lsl.w r3, lr, r12355; V7A-T-NEXT: it pl356; V7A-T-NEXT: movpl r3, #0357; V7A-T-NEXT: subs r3, #1358; V7A-T-NEXT: sbc r12, r4, #0359; V7A-T-NEXT: rsb.w r4, r2, #32360; V7A-T-NEXT: lsl.w r4, r1, r4361; V7A-T-NEXT: orrs r0, r4362; V7A-T-NEXT: subs.w r4, r2, #32363; V7A-T-NEXT: it pl364; V7A-T-NEXT: lsrpl.w r0, r1, r4365; V7A-T-NEXT: lsr.w r1, r1, r2366; V7A-T-NEXT: and.w r0, r0, r3367; V7A-T-NEXT: it pl368; V7A-T-NEXT: movpl r1, #0369; V7A-T-NEXT: and.w r1, r1, r12370; V7A-T-NEXT: pop {r4, pc}371;372; V6M-LABEL: bextr64_a0:373; V6M: @ %bb.0:374; V6M-NEXT: .save {r4, r5, r6, r7, lr}375; V6M-NEXT: push {r4, r5, r6, r7, lr}376; V6M-NEXT: .pad #12377; V6M-NEXT: sub sp, #12378; V6M-NEXT: str r2, [sp, #8] @ 4-byte Spill379; V6M-NEXT: str r1, [sp, #4] @ 4-byte Spill380; V6M-NEXT: mov r6, r0381; V6M-NEXT: movs r0, #1382; V6M-NEXT: movs r7, #0383; V6M-NEXT: ldr r2, [sp, #32]384; V6M-NEXT: mov r1, r7385; V6M-NEXT: bl __aeabi_llsl386; V6M-NEXT: mov r4, r1387; V6M-NEXT: subs r5, r0, #1388; V6M-NEXT: sbcs r4, r7389; V6M-NEXT: mov r0, r6390; V6M-NEXT: ldr r1, [sp, #4] @ 4-byte Reload391; V6M-NEXT: ldr r2, [sp, #8] @ 4-byte Reload392; V6M-NEXT: bl __aeabi_llsr393; V6M-NEXT: ands r0, r5394; V6M-NEXT: ands r1, r4395; V6M-NEXT: add sp, #12396; V6M-NEXT: pop {r4, r5, r6, r7, pc}397 %shifted = lshr i64 %val, %numskipbits398 %onebit = shl i64 1, %numlowbits399 %mask = add nsw i64 %onebit, -1400 %masked = and i64 %mask, %shifted401 ret i64 %masked402}403 404define i64 @bextr64_a0_arithmetic(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {405; V7M-LABEL: bextr64_a0_arithmetic:406; V7M: @ %bb.0:407; V7M-NEXT: .save {r4, lr}408; V7M-NEXT: push {r4, lr}409; V7M-NEXT: ldr.w r12, [sp, #8]410; V7M-NEXT: mov.w lr, #1411; V7M-NEXT: lsrs r0, r2412; V7M-NEXT: rsb.w r4, r12, #32413; V7M-NEXT: subs.w r3, r12, #32414; V7M-NEXT: lsr.w r4, lr, r4415; V7M-NEXT: it pl416; V7M-NEXT: lslpl.w r4, lr, r3417; V7M-NEXT: lsl.w r3, lr, r12418; V7M-NEXT: it pl419; V7M-NEXT: movpl r3, #0420; V7M-NEXT: subs r3, #1421; V7M-NEXT: sbc r12, r4, #0422; V7M-NEXT: rsb.w r4, r2, #32423; V7M-NEXT: lsl.w r4, r1, r4424; V7M-NEXT: orrs r0, r4425; V7M-NEXT: subs.w r4, r2, #32426; V7M-NEXT: it pl427; V7M-NEXT: asrpl.w r0, r1, r4428; V7M-NEXT: asr.w r2, r1, r2429; V7M-NEXT: and.w r0, r0, r3430; V7M-NEXT: it pl431; V7M-NEXT: asrpl r2, r1, #31432; V7M-NEXT: and.w r1, r12, r2433; V7M-NEXT: pop {r4, pc}434;435; V7A-LABEL: bextr64_a0_arithmetic:436; V7A: @ %bb.0:437; V7A-NEXT: .save {r4, r5, r11, lr}438; V7A-NEXT: push {r4, r5, r11, lr}439; V7A-NEXT: ldr lr, [sp, #16]440; V7A-NEXT: mov r5, #1441; V7A-NEXT: lsr r0, r0, r2442; V7A-NEXT: rsb r12, lr, #32443; V7A-NEXT: subs r4, lr, #32444; V7A-NEXT: lsr r3, r5, r12445; V7A-NEXT: lslpl r3, r5, r4446; V7A-NEXT: lsl r5, r5, lr447; V7A-NEXT: movwpl r5, #0448; V7A-NEXT: rsb r4, r2, #32449; V7A-NEXT: subs r5, r5, #1450; V7A-NEXT: sbc r3, r3, #0451; V7A-NEXT: orr r0, r0, r1, lsl r4452; V7A-NEXT: subs r4, r2, #32453; V7A-NEXT: asr r2, r1, r2454; V7A-NEXT: asrpl r2, r1, #31455; V7A-NEXT: asrpl r0, r1, r4456; V7A-NEXT: and r1, r3, r2457; V7A-NEXT: and r0, r5, r0458; V7A-NEXT: pop {r4, r5, r11, pc}459;460; V7A-T-LABEL: bextr64_a0_arithmetic:461; V7A-T: @ %bb.0:462; V7A-T-NEXT: .save {r4, lr}463; V7A-T-NEXT: push {r4, lr}464; V7A-T-NEXT: ldr.w r12, [sp, #8]465; V7A-T-NEXT: mov.w lr, #1466; V7A-T-NEXT: lsrs r0, r2467; V7A-T-NEXT: rsb.w r4, r12, #32468; V7A-T-NEXT: subs.w r3, r12, #32469; V7A-T-NEXT: lsr.w r4, lr, r4470; V7A-T-NEXT: it pl471; V7A-T-NEXT: lslpl.w r4, lr, r3472; V7A-T-NEXT: lsl.w r3, lr, r12473; V7A-T-NEXT: it pl474; V7A-T-NEXT: movpl r3, #0475; V7A-T-NEXT: subs r3, #1476; V7A-T-NEXT: sbc r12, r4, #0477; V7A-T-NEXT: rsb.w r4, r2, #32478; V7A-T-NEXT: lsl.w r4, r1, r4479; V7A-T-NEXT: orrs r0, r4480; V7A-T-NEXT: subs.w r4, r2, #32481; V7A-T-NEXT: it pl482; V7A-T-NEXT: asrpl.w r0, r1, r4483; V7A-T-NEXT: asr.w r2, r1, r2484; V7A-T-NEXT: and.w r0, r0, r3485; V7A-T-NEXT: it pl486; V7A-T-NEXT: asrpl r2, r1, #31487; V7A-T-NEXT: and.w r1, r12, r2488; V7A-T-NEXT: pop {r4, pc}489;490; V6M-LABEL: bextr64_a0_arithmetic:491; V6M: @ %bb.0:492; V6M-NEXT: .save {r4, r5, r6, r7, lr}493; V6M-NEXT: push {r4, r5, r6, r7, lr}494; V6M-NEXT: .pad #12495; V6M-NEXT: sub sp, #12496; V6M-NEXT: str r2, [sp, #8] @ 4-byte Spill497; V6M-NEXT: str r1, [sp, #4] @ 4-byte Spill498; V6M-NEXT: mov r6, r0499; V6M-NEXT: movs r0, #1500; V6M-NEXT: movs r7, #0501; V6M-NEXT: ldr r2, [sp, #32]502; V6M-NEXT: mov r1, r7503; V6M-NEXT: bl __aeabi_llsl504; V6M-NEXT: mov r4, r1505; V6M-NEXT: subs r5, r0, #1506; V6M-NEXT: sbcs r4, r7507; V6M-NEXT: mov r0, r6508; V6M-NEXT: ldr r1, [sp, #4] @ 4-byte Reload509; V6M-NEXT: ldr r2, [sp, #8] @ 4-byte Reload510; V6M-NEXT: bl __aeabi_lasr511; V6M-NEXT: ands r0, r5512; V6M-NEXT: ands r1, r4513; V6M-NEXT: add sp, #12514; V6M-NEXT: pop {r4, r5, r6, r7, pc}515 %shifted = ashr i64 %val, %numskipbits516 %onebit = shl i64 1, %numlowbits517 %mask = add nsw i64 %onebit, -1518 %masked = and i64 %mask, %shifted519 ret i64 %masked520}521 522define i64 @bextr64_a1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {523; V7M-LABEL: bextr64_a1_indexzext:524; V7M: @ %bb.0:525; V7M-NEXT: .save {r4, lr}526; V7M-NEXT: push {r4, lr}527; V7M-NEXT: rsb.w r4, r3, #32528; V7M-NEXT: mov.w lr, #1529; V7M-NEXT: subs.w r12, r3, #32530; V7M-NEXT: lsl.w r3, lr, r3531; V7M-NEXT: lsr.w r4, lr, r4532; V7M-NEXT: lsr.w r0, r0, r2533; V7M-NEXT: it pl534; V7M-NEXT: lslpl.w r4, lr, r12535; V7M-NEXT: it pl536; V7M-NEXT: movpl r3, #0537; V7M-NEXT: subs r3, #1538; V7M-NEXT: sbc r12, r4, #0539; V7M-NEXT: rsb.w r4, r2, #32540; V7M-NEXT: lsl.w r4, r1, r4541; V7M-NEXT: orrs r0, r4542; V7M-NEXT: subs.w r4, r2, #32543; V7M-NEXT: it pl544; V7M-NEXT: lsrpl.w r0, r1, r4545; V7M-NEXT: lsr.w r1, r1, r2546; V7M-NEXT: and.w r0, r0, r3547; V7M-NEXT: it pl548; V7M-NEXT: movpl r1, #0549; V7M-NEXT: and.w r1, r1, r12550; V7M-NEXT: pop {r4, pc}551;552; V7A-LABEL: bextr64_a1_indexzext:553; V7A: @ %bb.0:554; V7A-NEXT: .save {r4, lr}555; V7A-NEXT: push {r4, lr}556; V7A-NEXT: rsb r12, r3, #32557; V7A-NEXT: mov lr, #1558; V7A-NEXT: subs r4, r3, #32559; V7A-NEXT: lsl r3, lr, r3560; V7A-NEXT: lsr r12, lr, r12561; V7A-NEXT: movwpl r3, #0562; V7A-NEXT: lslpl r12, lr, r4563; V7A-NEXT: rsb r4, r2, #32564; V7A-NEXT: lsr r0, r0, r2565; V7A-NEXT: subs r3, r3, #1566; V7A-NEXT: sbc r12, r12, #0567; V7A-NEXT: orr r0, r0, r1, lsl r4568; V7A-NEXT: subs r4, r2, #32569; V7A-NEXT: lsrpl r0, r1, r4570; V7A-NEXT: lsr r1, r1, r2571; V7A-NEXT: movwpl r1, #0572; V7A-NEXT: and r0, r3, r0573; V7A-NEXT: and r1, r12, r1574; V7A-NEXT: pop {r4, pc}575;576; V7A-T-LABEL: bextr64_a1_indexzext:577; V7A-T: @ %bb.0:578; V7A-T-NEXT: .save {r4, lr}579; V7A-T-NEXT: push {r4, lr}580; V7A-T-NEXT: rsb.w r4, r3, #32581; V7A-T-NEXT: mov.w lr, #1582; V7A-T-NEXT: subs.w r12, r3, #32583; V7A-T-NEXT: lsl.w r3, lr, r3584; V7A-T-NEXT: lsr.w r4, lr, r4585; V7A-T-NEXT: lsr.w r0, r0, r2586; V7A-T-NEXT: it pl587; V7A-T-NEXT: lslpl.w r4, lr, r12588; V7A-T-NEXT: it pl589; V7A-T-NEXT: movpl r3, #0590; V7A-T-NEXT: subs r3, #1591; V7A-T-NEXT: sbc r12, r4, #0592; V7A-T-NEXT: rsb.w r4, r2, #32593; V7A-T-NEXT: lsl.w r4, r1, r4594; V7A-T-NEXT: orrs r0, r4595; V7A-T-NEXT: subs.w r4, r2, #32596; V7A-T-NEXT: it pl597; V7A-T-NEXT: lsrpl.w r0, r1, r4598; V7A-T-NEXT: lsr.w r1, r1, r2599; V7A-T-NEXT: and.w r0, r0, r3600; V7A-T-NEXT: it pl601; V7A-T-NEXT: movpl r1, #0602; V7A-T-NEXT: and.w r1, r1, r12603; V7A-T-NEXT: pop {r4, pc}604;605; V6M-LABEL: bextr64_a1_indexzext:606; V6M: @ %bb.0:607; V6M-NEXT: .save {r4, r5, r6, r7, lr}608; V6M-NEXT: push {r4, r5, r6, r7, lr}609; V6M-NEXT: .pad #12610; V6M-NEXT: sub sp, #12611; V6M-NEXT: str r2, [sp, #8] @ 4-byte Spill612; V6M-NEXT: str r1, [sp, #4] @ 4-byte Spill613; V6M-NEXT: mov r6, r0614; V6M-NEXT: movs r0, #1615; V6M-NEXT: movs r7, #0616; V6M-NEXT: mov r1, r7617; V6M-NEXT: mov r2, r3618; V6M-NEXT: bl __aeabi_llsl619; V6M-NEXT: mov r4, r1620; V6M-NEXT: subs r5, r0, #1621; V6M-NEXT: sbcs r4, r7622; V6M-NEXT: mov r0, r6623; V6M-NEXT: ldr r1, [sp, #4] @ 4-byte Reload624; V6M-NEXT: ldr r2, [sp, #8] @ 4-byte Reload625; V6M-NEXT: bl __aeabi_llsr626; V6M-NEXT: ands r0, r5627; V6M-NEXT: ands r1, r4628; V6M-NEXT: add sp, #12629; V6M-NEXT: pop {r4, r5, r6, r7, pc}630 %skip = zext i8 %numskipbits to i64631 %shifted = lshr i64 %val, %skip632 %conv = zext i8 %numlowbits to i64633 %onebit = shl i64 1, %conv634 %mask = add nsw i64 %onebit, -1635 %masked = and i64 %mask, %shifted636 ret i64 %masked637}638 639define i64 @bextr64_a2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {640; V7M-LABEL: bextr64_a2_load:641; V7M: @ %bb.0:642; V7M-NEXT: .save {r7, lr}643; V7M-NEXT: push {r7, lr}644; V7M-NEXT: ldr.w r12, [sp, #8]645; V7M-NEXT: mov.w lr, #1646; V7M-NEXT: rsb.w r1, r12, #32647; V7M-NEXT: subs.w r3, r12, #32648; V7M-NEXT: lsr.w r1, lr, r1649; V7M-NEXT: it pl650; V7M-NEXT: lslpl.w r1, lr, r3651; V7M-NEXT: lsl.w r3, lr, r12652; V7M-NEXT: it pl653; V7M-NEXT: movpl r3, #0654; V7M-NEXT: subs.w lr, r3, #1655; V7M-NEXT: ldrd r0, r3, [r0]656; V7M-NEXT: sbc r12, r1, #0657; V7M-NEXT: rsb.w r1, r2, #32658; V7M-NEXT: lsl.w r1, r3, r1659; V7M-NEXT: lsrs r0, r2660; V7M-NEXT: orrs r0, r1661; V7M-NEXT: subs.w r1, r2, #32662; V7M-NEXT: it pl663; V7M-NEXT: lsrpl.w r0, r3, r1664; V7M-NEXT: lsr.w r1, r3, r2665; V7M-NEXT: it pl666; V7M-NEXT: movpl r1, #0667; V7M-NEXT: and.w r0, r0, lr668; V7M-NEXT: and.w r1, r1, r12669; V7M-NEXT: pop {r7, pc}670;671; V7A-LABEL: bextr64_a2_load:672; V7A: @ %bb.0:673; V7A-NEXT: .save {r4, r5, r6, lr}674; V7A-NEXT: push {r4, r5, r6, lr}675; V7A-NEXT: ldr r1, [sp, #16]676; V7A-NEXT: mov r3, #1677; V7A-NEXT: ldr r6, [r0]678; V7A-NEXT: ldr r5, [r0, #4]679; V7A-NEXT: rsb r0, r1, #32680; V7A-NEXT: subs r4, r1, #32681; V7A-NEXT: lsl r1, r3, r1682; V7A-NEXT: lsr r0, r3, r0683; V7A-NEXT: movwpl r1, #0684; V7A-NEXT: lslpl r0, r3, r4685; V7A-NEXT: subs r1, r1, #1686; V7A-NEXT: sbc r3, r0, #0687; V7A-NEXT: lsr r0, r6, r2688; V7A-NEXT: rsb r6, r2, #32689; V7A-NEXT: orr r0, r0, r5, lsl r6690; V7A-NEXT: subs r6, r2, #32691; V7A-NEXT: lsrpl r0, r5, r6692; V7A-NEXT: and r0, r1, r0693; V7A-NEXT: lsr r1, r5, r2694; V7A-NEXT: movwpl r1, #0695; V7A-NEXT: and r1, r3, r1696; V7A-NEXT: pop {r4, r5, r6, pc}697;698; V7A-T-LABEL: bextr64_a2_load:699; V7A-T: @ %bb.0:700; V7A-T-NEXT: .save {r4, lr}701; V7A-T-NEXT: push {r4, lr}702; V7A-T-NEXT: ldr.w r12, [sp, #8]703; V7A-T-NEXT: movs r3, #1704; V7A-T-NEXT: ldrd lr, r1, [r0]705; V7A-T-NEXT: rsb.w r4, r12, #32706; V7A-T-NEXT: subs.w r0, r12, #32707; V7A-T-NEXT: lsr.w r4, r3, r4708; V7A-T-NEXT: it pl709; V7A-T-NEXT: lslpl.w r4, r3, r0710; V7A-T-NEXT: lsl.w r0, r3, r12711; V7A-T-NEXT: it pl712; V7A-T-NEXT: movpl r0, #0713; V7A-T-NEXT: lsr.w r3, lr, r2714; V7A-T-NEXT: subs r0, #1715; V7A-T-NEXT: sbc r12, r4, #0716; V7A-T-NEXT: rsb.w r4, r2, #32717; V7A-T-NEXT: lsl.w r4, r1, r4718; V7A-T-NEXT: orrs r3, r4719; V7A-T-NEXT: subs.w r4, r2, #32720; V7A-T-NEXT: it pl721; V7A-T-NEXT: lsrpl.w r3, r1, r4722; V7A-T-NEXT: lsr.w r1, r1, r2723; V7A-T-NEXT: and.w r0, r0, r3724; V7A-T-NEXT: it pl725; V7A-T-NEXT: movpl r1, #0726; V7A-T-NEXT: and.w r1, r1, r12727; V7A-T-NEXT: pop {r4, pc}728;729; V6M-LABEL: bextr64_a2_load:730; V6M: @ %bb.0:731; V6M-NEXT: .save {r4, r5, r6, r7, lr}732; V6M-NEXT: push {r4, r5, r6, r7, lr}733; V6M-NEXT: .pad #4734; V6M-NEXT: sub sp, #4735; V6M-NEXT: str r2, [sp] @ 4-byte Spill736; V6M-NEXT: mov r5, r0737; V6M-NEXT: movs r0, #1738; V6M-NEXT: movs r7, #0739; V6M-NEXT: ldr r2, [sp, #24]740; V6M-NEXT: mov r1, r7741; V6M-NEXT: bl __aeabi_llsl742; V6M-NEXT: mov r6, r1743; V6M-NEXT: subs r4, r0, #1744; V6M-NEXT: sbcs r6, r7745; V6M-NEXT: ldm r5!, {r0, r1}746; V6M-NEXT: ldr r2, [sp] @ 4-byte Reload747; V6M-NEXT: bl __aeabi_llsr748; V6M-NEXT: ands r0, r4749; V6M-NEXT: ands r1, r6750; V6M-NEXT: add sp, #4751; V6M-NEXT: pop {r4, r5, r6, r7, pc}752 %val = load i64, ptr %w753 %shifted = lshr i64 %val, %numskipbits754 %onebit = shl i64 1, %numlowbits755 %mask = add nsw i64 %onebit, -1756 %masked = and i64 %mask, %shifted757 ret i64 %masked758}759 760define i64 @bextr64_a3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {761; V7M-LABEL: bextr64_a3_load_indexzext:762; V7M: @ %bb.0:763; V7M-NEXT: .save {r7, lr}764; V7M-NEXT: push {r7, lr}765; V7M-NEXT: rsb.w r3, r2, #32766; V7M-NEXT: mov.w r12, #1767; V7M-NEXT: subs.w lr, r2, #32768; V7M-NEXT: lsl.w r2, r12, r2769; V7M-NEXT: lsr.w r3, r12, r3770; V7M-NEXT: it pl771; V7M-NEXT: lslpl.w r3, r12, lr772; V7M-NEXT: it pl773; V7M-NEXT: movpl r2, #0774; V7M-NEXT: subs.w lr, r2, #1775; V7M-NEXT: ldrd r0, r2, [r0]776; V7M-NEXT: sbc r12, r3, #0777; V7M-NEXT: rsb.w r3, r1, #32778; V7M-NEXT: lsl.w r3, r2, r3779; V7M-NEXT: lsrs r0, r1780; V7M-NEXT: orrs r0, r3781; V7M-NEXT: subs.w r3, r1, #32782; V7M-NEXT: lsr.w r1, r2, r1783; V7M-NEXT: it pl784; V7M-NEXT: lsrpl.w r0, r2, r3785; V7M-NEXT: it pl786; V7M-NEXT: movpl r1, #0787; V7M-NEXT: and.w r0, r0, lr788; V7M-NEXT: and.w r1, r1, r12789; V7M-NEXT: pop {r7, pc}790;791; V7A-LABEL: bextr64_a3_load_indexzext:792; V7A: @ %bb.0:793; V7A-NEXT: .save {r4, r5, r6, lr}794; V7A-NEXT: push {r4, r5, r6, lr}795; V7A-NEXT: ldr r6, [r0]796; V7A-NEXT: mov r3, #1797; V7A-NEXT: ldr r5, [r0, #4]798; V7A-NEXT: rsb r0, r2, #32799; V7A-NEXT: subs r4, r2, #32800; V7A-NEXT: lsl r2, r3, r2801; V7A-NEXT: lsr r0, r3, r0802; V7A-NEXT: movwpl r2, #0803; V7A-NEXT: lslpl r0, r3, r4804; V7A-NEXT: subs r3, r2, #1805; V7A-NEXT: sbc r0, r0, #0806; V7A-NEXT: lsr r2, r5, r1807; V7A-NEXT: subs r4, r1, #32808; V7A-NEXT: movwpl r2, #0809; V7A-NEXT: and r2, r0, r2810; V7A-NEXT: lsr r0, r6, r1811; V7A-NEXT: rsb r1, r1, #32812; V7A-NEXT: orr r0, r0, r5, lsl r1813; V7A-NEXT: mov r1, r2814; V7A-NEXT: lsrpl r0, r5, r4815; V7A-NEXT: and r0, r3, r0816; V7A-NEXT: pop {r4, r5, r6, pc}817;818; V7A-T-LABEL: bextr64_a3_load_indexzext:819; V7A-T: @ %bb.0:820; V7A-T-NEXT: .save {r4, lr}821; V7A-T-NEXT: push {r4, lr}822; V7A-T-NEXT: rsb.w r4, r2, #32823; V7A-T-NEXT: mov.w lr, #1824; V7A-T-NEXT: subs.w r3, r2, #32825; V7A-T-NEXT: lsl.w r2, lr, r2826; V7A-T-NEXT: lsr.w r4, lr, r4827; V7A-T-NEXT: ldrd r12, r0, [r0]828; V7A-T-NEXT: it pl829; V7A-T-NEXT: lslpl.w r4, lr, r3830; V7A-T-NEXT: it pl831; V7A-T-NEXT: movpl r2, #0832; V7A-T-NEXT: subs.w lr, r2, #1833; V7A-T-NEXT: sbc r2, r4, #0834; V7A-T-NEXT: lsr.w r4, r0, r1835; V7A-T-NEXT: subs.w r3, r1, #32836; V7A-T-NEXT: it pl837; V7A-T-NEXT: movpl r4, #0838; V7A-T-NEXT: and.w r2, r2, r4839; V7A-T-NEXT: rsb.w r4, r1, #32840; V7A-T-NEXT: lsr.w r1, r12, r1841; V7A-T-NEXT: lsl.w r4, r0, r4842; V7A-T-NEXT: orr.w r1, r1, r4843; V7A-T-NEXT: it pl844; V7A-T-NEXT: lsrpl.w r1, r0, r3845; V7A-T-NEXT: and.w r0, lr, r1846; V7A-T-NEXT: mov r1, r2847; V7A-T-NEXT: pop {r4, pc}848;849; V6M-LABEL: bextr64_a3_load_indexzext:850; V6M: @ %bb.0:851; V6M-NEXT: .save {r4, r5, r6, r7, lr}852; V6M-NEXT: push {r4, r5, r6, r7, lr}853; V6M-NEXT: .pad #4854; V6M-NEXT: sub sp, #4855; V6M-NEXT: str r1, [sp] @ 4-byte Spill856; V6M-NEXT: mov r6, r0857; V6M-NEXT: movs r0, #1858; V6M-NEXT: movs r7, #0859; V6M-NEXT: mov r1, r7860; V6M-NEXT: bl __aeabi_llsl861; V6M-NEXT: mov r5, r1862; V6M-NEXT: subs r4, r0, #1863; V6M-NEXT: sbcs r5, r7864; V6M-NEXT: ldm r6!, {r0, r1}865; V6M-NEXT: ldr r2, [sp] @ 4-byte Reload866; V6M-NEXT: bl __aeabi_llsr867; V6M-NEXT: ands r0, r4868; V6M-NEXT: ands r1, r5869; V6M-NEXT: add sp, #4870; V6M-NEXT: pop {r4, r5, r6, r7, pc}871 %val = load i64, ptr %w872 %skip = zext i8 %numskipbits to i64873 %shifted = lshr i64 %val, %skip874 %conv = zext i8 %numlowbits to i64875 %onebit = shl i64 1, %conv876 %mask = add nsw i64 %onebit, -1877 %masked = and i64 %mask, %shifted878 ret i64 %masked879}880 881define i64 @bextr64_a4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {882; V7M-LABEL: bextr64_a4_commutative:883; V7M: @ %bb.0:884; V7M-NEXT: .save {r4, lr}885; V7M-NEXT: push {r4, lr}886; V7M-NEXT: ldr.w r12, [sp, #8]887; V7M-NEXT: mov.w lr, #1888; V7M-NEXT: lsrs r0, r2889; V7M-NEXT: rsb.w r4, r12, #32890; V7M-NEXT: subs.w r3, r12, #32891; V7M-NEXT: lsr.w r4, lr, r4892; V7M-NEXT: it pl893; V7M-NEXT: lslpl.w r4, lr, r3894; V7M-NEXT: lsl.w r3, lr, r12895; V7M-NEXT: it pl896; V7M-NEXT: movpl r3, #0897; V7M-NEXT: subs r3, #1898; V7M-NEXT: sbc r12, r4, #0899; V7M-NEXT: rsb.w r4, r2, #32900; V7M-NEXT: lsl.w r4, r1, r4901; V7M-NEXT: orrs r0, r4902; V7M-NEXT: subs.w r4, r2, #32903; V7M-NEXT: it pl904; V7M-NEXT: lsrpl.w r0, r1, r4905; V7M-NEXT: lsr.w r1, r1, r2906; V7M-NEXT: and.w r0, r0, r3907; V7M-NEXT: it pl908; V7M-NEXT: movpl r1, #0909; V7M-NEXT: and.w r1, r1, r12910; V7M-NEXT: pop {r4, pc}911;912; V7A-LABEL: bextr64_a4_commutative:913; V7A: @ %bb.0:914; V7A-NEXT: .save {r4, r5, r11, lr}915; V7A-NEXT: push {r4, r5, r11, lr}916; V7A-NEXT: ldr lr, [sp, #16]917; V7A-NEXT: mov r5, #1918; V7A-NEXT: lsr r0, r0, r2919; V7A-NEXT: rsb r12, lr, #32920; V7A-NEXT: subs r4, lr, #32921; V7A-NEXT: lsr r3, r5, r12922; V7A-NEXT: lslpl r3, r5, r4923; V7A-NEXT: lsl r5, r5, lr924; V7A-NEXT: movwpl r5, #0925; V7A-NEXT: rsb r4, r2, #32926; V7A-NEXT: subs r5, r5, #1927; V7A-NEXT: sbc r3, r3, #0928; V7A-NEXT: orr r0, r0, r1, lsl r4929; V7A-NEXT: subs r4, r2, #32930; V7A-NEXT: lsrpl r0, r1, r4931; V7A-NEXT: lsr r1, r1, r2932; V7A-NEXT: movwpl r1, #0933; V7A-NEXT: and r0, r0, r5934; V7A-NEXT: and r1, r1, r3935; V7A-NEXT: pop {r4, r5, r11, pc}936;937; V7A-T-LABEL: bextr64_a4_commutative:938; V7A-T: @ %bb.0:939; V7A-T-NEXT: .save {r4, lr}940; V7A-T-NEXT: push {r4, lr}941; V7A-T-NEXT: ldr.w r12, [sp, #8]942; V7A-T-NEXT: mov.w lr, #1943; V7A-T-NEXT: lsrs r0, r2944; V7A-T-NEXT: rsb.w r4, r12, #32945; V7A-T-NEXT: subs.w r3, r12, #32946; V7A-T-NEXT: lsr.w r4, lr, r4947; V7A-T-NEXT: it pl948; V7A-T-NEXT: lslpl.w r4, lr, r3949; V7A-T-NEXT: lsl.w r3, lr, r12950; V7A-T-NEXT: it pl951; V7A-T-NEXT: movpl r3, #0952; V7A-T-NEXT: subs r3, #1953; V7A-T-NEXT: sbc r12, r4, #0954; V7A-T-NEXT: rsb.w r4, r2, #32955; V7A-T-NEXT: lsl.w r4, r1, r4956; V7A-T-NEXT: orrs r0, r4957; V7A-T-NEXT: subs.w r4, r2, #32958; V7A-T-NEXT: it pl959; V7A-T-NEXT: lsrpl.w r0, r1, r4960; V7A-T-NEXT: lsr.w r1, r1, r2961; V7A-T-NEXT: and.w r0, r0, r3962; V7A-T-NEXT: it pl963; V7A-T-NEXT: movpl r1, #0964; V7A-T-NEXT: and.w r1, r1, r12965; V7A-T-NEXT: pop {r4, pc}966;967; V6M-LABEL: bextr64_a4_commutative:968; V6M: @ %bb.0:969; V6M-NEXT: .save {r4, r5, r6, r7, lr}970; V6M-NEXT: push {r4, r5, r6, r7, lr}971; V6M-NEXT: .pad #12972; V6M-NEXT: sub sp, #12973; V6M-NEXT: str r2, [sp, #8] @ 4-byte Spill974; V6M-NEXT: str r1, [sp, #4] @ 4-byte Spill975; V6M-NEXT: mov r6, r0976; V6M-NEXT: movs r0, #1977; V6M-NEXT: movs r7, #0978; V6M-NEXT: ldr r2, [sp, #32]979; V6M-NEXT: mov r1, r7980; V6M-NEXT: bl __aeabi_llsl981; V6M-NEXT: mov r4, r1982; V6M-NEXT: subs r5, r0, #1983; V6M-NEXT: sbcs r4, r7984; V6M-NEXT: mov r0, r6985; V6M-NEXT: ldr r1, [sp, #4] @ 4-byte Reload986; V6M-NEXT: ldr r2, [sp, #8] @ 4-byte Reload987; V6M-NEXT: bl __aeabi_llsr988; V6M-NEXT: ands r0, r5989; V6M-NEXT: ands r1, r4990; V6M-NEXT: add sp, #12991; V6M-NEXT: pop {r4, r5, r6, r7, pc}992 %shifted = lshr i64 %val, %numskipbits993 %onebit = shl i64 1, %numlowbits994 %mask = add nsw i64 %onebit, -1995 %masked = and i64 %shifted, %mask ; swapped order996 ret i64 %masked997}998 999; 64-bit, but with 32-bit output1000 1001; Everything done in 64-bit, truncation happens last.1002define i32 @bextr64_32_a0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {1003; V7M-LABEL: bextr64_32_a0:1004; V7M: @ %bb.0:1005; V7M-NEXT: rsb.w r3, r2, #321006; V7M-NEXT: lsrs r0, r21007; V7M-NEXT: subs r2, #321008; V7M-NEXT: lsl.w r3, r1, r31009; V7M-NEXT: orr.w r0, r0, r31010; V7M-NEXT: it pl1011; V7M-NEXT: lsrpl.w r0, r1, r21012; V7M-NEXT: ldr r1, [sp]1013; V7M-NEXT: movs r2, #11014; V7M-NEXT: lsls r2, r11015; V7M-NEXT: subs r1, #321016; V7M-NEXT: it pl1017; V7M-NEXT: movpl r2, #01018; V7M-NEXT: subs r1, r2, #11019; V7M-NEXT: ands r0, r11020; V7M-NEXT: bx lr1021;1022; V7A-LABEL: bextr64_32_a0:1023; V7A: @ %bb.0:1024; V7A-NEXT: rsb r3, r2, #321025; V7A-NEXT: lsr r0, r0, r21026; V7A-NEXT: ldr r12, [sp]1027; V7A-NEXT: subs r2, r2, #321028; V7A-NEXT: orr r0, r0, r1, lsl r31029; V7A-NEXT: lsrpl r0, r1, r21030; V7A-NEXT: mov r1, #11031; V7A-NEXT: lsl r1, r1, r121032; V7A-NEXT: subs r2, r12, #321033; V7A-NEXT: movwpl r1, #01034; V7A-NEXT: sub r1, r1, #11035; V7A-NEXT: and r0, r1, r01036; V7A-NEXT: bx lr1037;1038; V7A-T-LABEL: bextr64_32_a0:1039; V7A-T: @ %bb.0:1040; V7A-T-NEXT: rsb.w r3, r2, #321041; V7A-T-NEXT: lsrs r0, r21042; V7A-T-NEXT: ldr.w r12, [sp]1043; V7A-T-NEXT: subs r2, #321044; V7A-T-NEXT: lsl.w r3, r1, r31045; V7A-T-NEXT: orr.w r0, r0, r31046; V7A-T-NEXT: it pl1047; V7A-T-NEXT: lsrpl.w r0, r1, r21048; V7A-T-NEXT: movs r1, #11049; V7A-T-NEXT: lsl.w r1, r1, r121050; V7A-T-NEXT: subs.w r2, r12, #321051; V7A-T-NEXT: it pl1052; V7A-T-NEXT: movpl r1, #01053; V7A-T-NEXT: subs r1, #11054; V7A-T-NEXT: ands r0, r11055; V7A-T-NEXT: bx lr1056;1057; V6M-LABEL: bextr64_32_a0:1058; V6M: @ %bb.0:1059; V6M-NEXT: .save {r4, lr}1060; V6M-NEXT: push {r4, lr}1061; V6M-NEXT: bl __aeabi_llsr1062; V6M-NEXT: mov r4, r01063; V6M-NEXT: movs r0, #11064; V6M-NEXT: movs r1, #01065; V6M-NEXT: ldr r2, [sp, #8]1066; V6M-NEXT: bl __aeabi_llsl1067; V6M-NEXT: subs r0, r0, #11068; V6M-NEXT: ands r0, r41069; V6M-NEXT: pop {r4, pc}1070 %shifted = lshr i64 %val, %numskipbits1071 %onebit = shl i64 1, %numlowbits1072 %mask = add nsw i64 %onebit, -11073 %masked = and i64 %mask, %shifted1074 %res = trunc i64 %masked to i321075 ret i32 %res1076}1077 1078; Shifting happens in 64-bit, then truncation. Masking is 32-bit.1079define i32 @bextr64_32_a1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {1080; V7M-LABEL: bextr64_32_a1:1081; V7M: @ %bb.0:1082; V7M-NEXT: rsb.w r3, r2, #321083; V7M-NEXT: lsrs r0, r21084; V7M-NEXT: subs r2, #321085; V7M-NEXT: lsl.w r3, r1, r31086; V7M-NEXT: orr.w r0, r0, r31087; V7M-NEXT: it pl1088; V7M-NEXT: lsrpl.w r0, r1, r21089; V7M-NEXT: ldr r1, [sp]1090; V7M-NEXT: movs r2, #11091; V7M-NEXT: lsl.w r1, r2, r11092; V7M-NEXT: subs r1, #11093; V7M-NEXT: ands r0, r11094; V7M-NEXT: bx lr1095;1096; V7A-LABEL: bextr64_32_a1:1097; V7A: @ %bb.0:1098; V7A-NEXT: .save {r11, lr}1099; V7A-NEXT: push {r11, lr}1100; V7A-NEXT: ldr r12, [sp, #8]1101; V7A-NEXT: mov lr, #11102; V7A-NEXT: mvn r3, #01103; V7A-NEXT: lsr r0, r0, r21104; V7A-NEXT: add r12, r3, lr, lsl r121105; V7A-NEXT: rsb r3, r2, #321106; V7A-NEXT: subs r2, r2, #321107; V7A-NEXT: orr r0, r0, r1, lsl r31108; V7A-NEXT: lsrpl r0, r1, r21109; V7A-NEXT: and r0, r12, r01110; V7A-NEXT: pop {r11, pc}1111;1112; V7A-T-LABEL: bextr64_32_a1:1113; V7A-T: @ %bb.0:1114; V7A-T-NEXT: rsb.w r3, r2, #321115; V7A-T-NEXT: lsrs r0, r21116; V7A-T-NEXT: ldr.w r12, [sp]1117; V7A-T-NEXT: subs r2, #321118; V7A-T-NEXT: lsl.w r3, r1, r31119; V7A-T-NEXT: orr.w r0, r0, r31120; V7A-T-NEXT: it pl1121; V7A-T-NEXT: lsrpl.w r0, r1, r21122; V7A-T-NEXT: movs r1, #11123; V7A-T-NEXT: lsl.w r1, r1, r121124; V7A-T-NEXT: subs r1, #11125; V7A-T-NEXT: ands r0, r11126; V7A-T-NEXT: bx lr1127;1128; V6M-LABEL: bextr64_32_a1:1129; V6M: @ %bb.0:1130; V6M-NEXT: .save {r7, lr}1131; V6M-NEXT: push {r7, lr}1132; V6M-NEXT: bl __aeabi_llsr1133; V6M-NEXT: ldr r1, [sp, #8]1134; V6M-NEXT: movs r2, #11135; V6M-NEXT: lsls r2, r11136; V6M-NEXT: subs r1, r2, #11137; V6M-NEXT: ands r0, r11138; V6M-NEXT: pop {r7, pc}1139 %shifted = lshr i64 %val, %numskipbits1140 %truncshifted = trunc i64 %shifted to i321141 %onebit = shl i32 1, %numlowbits1142 %mask = add nsw i32 %onebit, -11143 %masked = and i32 %mask, %truncshifted1144 ret i32 %masked1145}1146 1147; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.1148; Masking is 64-bit. Then truncation.1149define i32 @bextr64_32_a2(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {1150; V7M-LABEL: bextr64_32_a2:1151; V7M: @ %bb.0:1152; V7M-NEXT: rsb.w r3, r2, #321153; V7M-NEXT: lsrs r0, r21154; V7M-NEXT: subs r2, #321155; V7M-NEXT: lsl.w r3, r1, r31156; V7M-NEXT: orr.w r0, r0, r31157; V7M-NEXT: it pl1158; V7M-NEXT: lsrpl.w r0, r1, r21159; V7M-NEXT: ldr r1, [sp]1160; V7M-NEXT: movs r2, #11161; V7M-NEXT: lsl.w r1, r2, r11162; V7M-NEXT: subs r1, #11163; V7M-NEXT: ands r0, r11164; V7M-NEXT: bx lr1165;1166; V7A-LABEL: bextr64_32_a2:1167; V7A: @ %bb.0:1168; V7A-NEXT: .save {r11, lr}1169; V7A-NEXT: push {r11, lr}1170; V7A-NEXT: ldr r12, [sp, #8]1171; V7A-NEXT: mov lr, #11172; V7A-NEXT: mvn r3, #01173; V7A-NEXT: lsr r0, r0, r21174; V7A-NEXT: add r12, r3, lr, lsl r121175; V7A-NEXT: rsb r3, r2, #321176; V7A-NEXT: subs r2, r2, #321177; V7A-NEXT: orr r0, r0, r1, lsl r31178; V7A-NEXT: lsrpl r0, r1, r21179; V7A-NEXT: and r0, r12, r01180; V7A-NEXT: pop {r11, pc}1181;1182; V7A-T-LABEL: bextr64_32_a2:1183; V7A-T: @ %bb.0:1184; V7A-T-NEXT: rsb.w r3, r2, #321185; V7A-T-NEXT: lsrs r0, r21186; V7A-T-NEXT: ldr.w r12, [sp]1187; V7A-T-NEXT: subs r2, #321188; V7A-T-NEXT: lsl.w r3, r1, r31189; V7A-T-NEXT: orr.w r0, r0, r31190; V7A-T-NEXT: it pl1191; V7A-T-NEXT: lsrpl.w r0, r1, r21192; V7A-T-NEXT: movs r1, #11193; V7A-T-NEXT: lsl.w r1, r1, r121194; V7A-T-NEXT: subs r1, #11195; V7A-T-NEXT: ands r0, r11196; V7A-T-NEXT: bx lr1197;1198; V6M-LABEL: bextr64_32_a2:1199; V6M: @ %bb.0:1200; V6M-NEXT: .save {r7, lr}1201; V6M-NEXT: push {r7, lr}1202; V6M-NEXT: bl __aeabi_llsr1203; V6M-NEXT: ldr r1, [sp, #8]1204; V6M-NEXT: movs r2, #11205; V6M-NEXT: lsls r2, r11206; V6M-NEXT: subs r1, r2, #11207; V6M-NEXT: ands r0, r11208; V6M-NEXT: pop {r7, pc}1209 %shifted = lshr i64 %val, %numskipbits1210 %onebit = shl i32 1, %numlowbits1211 %mask = add nsw i32 %onebit, -11212 %zextmask = zext i32 %mask to i641213 %masked = and i64 %zextmask, %shifted1214 %truncmasked = trunc i64 %masked to i321215 ret i32 %truncmasked1216}1217 1218; ---------------------------------------------------------------------------- ;1219; Pattern b. 32-bit1220; ---------------------------------------------------------------------------- ;1221 1222define i32 @bextr32_b0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {1223; V7M-LABEL: bextr32_b0:1224; V7M: @ %bb.0:1225; V7M-NEXT: mov.w r3, #-11226; V7M-NEXT: lsrs r0, r11227; V7M-NEXT: lsl.w r2, r3, r21228; V7M-NEXT: bics r0, r21229; V7M-NEXT: bx lr1230;1231; V7A-LABEL: bextr32_b0:1232; V7A: @ %bb.0:1233; V7A-NEXT: lsr r0, r0, r11234; V7A-NEXT: mvn r1, #01235; V7A-NEXT: bic r0, r0, r1, lsl r21236; V7A-NEXT: bx lr1237;1238; V7A-T-LABEL: bextr32_b0:1239; V7A-T: @ %bb.0:1240; V7A-T-NEXT: mov.w r3, #-11241; V7A-T-NEXT: lsrs r0, r11242; V7A-T-NEXT: lsl.w r2, r3, r21243; V7A-T-NEXT: bics r0, r21244; V7A-T-NEXT: bx lr1245;1246; V6M-LABEL: bextr32_b0:1247; V6M: @ %bb.0:1248; V6M-NEXT: lsrs r0, r11249; V6M-NEXT: movs r1, #01250; V6M-NEXT: mvns r1, r11251; V6M-NEXT: lsls r1, r21252; V6M-NEXT: bics r0, r11253; V6M-NEXT: bx lr1254 %shifted = lshr i32 %val, %numskipbits1255 %notmask = shl i32 -1, %numlowbits1256 %mask = xor i32 %notmask, -11257 %masked = and i32 %mask, %shifted1258 ret i32 %masked1259}1260 1261define i32 @bextr32_b1_indexzext(i32 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {1262; V7M-LABEL: bextr32_b1_indexzext:1263; V7M: @ %bb.0:1264; V7M-NEXT: mov.w r3, #-11265; V7M-NEXT: lsrs r0, r11266; V7M-NEXT: lsl.w r2, r3, r21267; V7M-NEXT: bics r0, r21268; V7M-NEXT: bx lr1269;1270; V7A-LABEL: bextr32_b1_indexzext:1271; V7A: @ %bb.0:1272; V7A-NEXT: lsr r0, r0, r11273; V7A-NEXT: mvn r1, #01274; V7A-NEXT: bic r0, r0, r1, lsl r21275; V7A-NEXT: bx lr1276;1277; V7A-T-LABEL: bextr32_b1_indexzext:1278; V7A-T: @ %bb.0:1279; V7A-T-NEXT: mov.w r3, #-11280; V7A-T-NEXT: lsrs r0, r11281; V7A-T-NEXT: lsl.w r2, r3, r21282; V7A-T-NEXT: bics r0, r21283; V7A-T-NEXT: bx lr1284;1285; V6M-LABEL: bextr32_b1_indexzext:1286; V6M: @ %bb.0:1287; V6M-NEXT: lsrs r0, r11288; V6M-NEXT: movs r1, #01289; V6M-NEXT: mvns r1, r11290; V6M-NEXT: lsls r1, r21291; V6M-NEXT: bics r0, r11292; V6M-NEXT: bx lr1293 %skip = zext i8 %numskipbits to i321294 %shifted = lshr i32 %val, %skip1295 %conv = zext i8 %numlowbits to i321296 %notmask = shl i32 -1, %conv1297 %mask = xor i32 %notmask, -11298 %masked = and i32 %mask, %shifted1299 ret i32 %masked1300}1301 1302define i32 @bextr32_b2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {1303; V7M-LABEL: bextr32_b2_load:1304; V7M: @ %bb.0:1305; V7M-NEXT: ldr r0, [r0]1306; V7M-NEXT: mov.w r3, #-11307; V7M-NEXT: lsl.w r2, r3, r21308; V7M-NEXT: lsrs r0, r11309; V7M-NEXT: bics r0, r21310; V7M-NEXT: bx lr1311;1312; V7A-LABEL: bextr32_b2_load:1313; V7A: @ %bb.0:1314; V7A-NEXT: ldr r0, [r0]1315; V7A-NEXT: lsr r0, r0, r11316; V7A-NEXT: mvn r1, #01317; V7A-NEXT: bic r0, r0, r1, lsl r21318; V7A-NEXT: bx lr1319;1320; V7A-T-LABEL: bextr32_b2_load:1321; V7A-T: @ %bb.0:1322; V7A-T-NEXT: ldr r0, [r0]1323; V7A-T-NEXT: mov.w r3, #-11324; V7A-T-NEXT: lsl.w r2, r3, r21325; V7A-T-NEXT: lsrs r0, r11326; V7A-T-NEXT: bics r0, r21327; V7A-T-NEXT: bx lr1328;1329; V6M-LABEL: bextr32_b2_load:1330; V6M: @ %bb.0:1331; V6M-NEXT: movs r3, #01332; V6M-NEXT: mvns r3, r31333; V6M-NEXT: lsls r3, r21334; V6M-NEXT: ldr r0, [r0]1335; V6M-NEXT: lsrs r0, r11336; V6M-NEXT: bics r0, r31337; V6M-NEXT: bx lr1338 %val = load i32, ptr %w1339 %shifted = lshr i32 %val, %numskipbits1340 %notmask = shl i32 -1, %numlowbits1341 %mask = xor i32 %notmask, -11342 %masked = and i32 %mask, %shifted1343 ret i32 %masked1344}1345 1346define i32 @bextr32_b3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {1347; V7M-LABEL: bextr32_b3_load_indexzext:1348; V7M: @ %bb.0:1349; V7M-NEXT: ldr r0, [r0]1350; V7M-NEXT: mov.w r3, #-11351; V7M-NEXT: lsl.w r2, r3, r21352; V7M-NEXT: lsrs r0, r11353; V7M-NEXT: bics r0, r21354; V7M-NEXT: bx lr1355;1356; V7A-LABEL: bextr32_b3_load_indexzext:1357; V7A: @ %bb.0:1358; V7A-NEXT: ldr r0, [r0]1359; V7A-NEXT: lsr r0, r0, r11360; V7A-NEXT: mvn r1, #01361; V7A-NEXT: bic r0, r0, r1, lsl r21362; V7A-NEXT: bx lr1363;1364; V7A-T-LABEL: bextr32_b3_load_indexzext:1365; V7A-T: @ %bb.0:1366; V7A-T-NEXT: ldr r0, [r0]1367; V7A-T-NEXT: mov.w r3, #-11368; V7A-T-NEXT: lsl.w r2, r3, r21369; V7A-T-NEXT: lsrs r0, r11370; V7A-T-NEXT: bics r0, r21371; V7A-T-NEXT: bx lr1372;1373; V6M-LABEL: bextr32_b3_load_indexzext:1374; V6M: @ %bb.0:1375; V6M-NEXT: movs r3, #01376; V6M-NEXT: mvns r3, r31377; V6M-NEXT: lsls r3, r21378; V6M-NEXT: ldr r0, [r0]1379; V6M-NEXT: lsrs r0, r11380; V6M-NEXT: bics r0, r31381; V6M-NEXT: bx lr1382 %val = load i32, ptr %w1383 %skip = zext i8 %numskipbits to i321384 %shifted = lshr i32 %val, %skip1385 %conv = zext i8 %numlowbits to i321386 %notmask = shl i32 -1, %conv1387 %mask = xor i32 %notmask, -11388 %masked = and i32 %mask, %shifted1389 ret i32 %masked1390}1391 1392define i32 @bextr32_b4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {1393; V7M-LABEL: bextr32_b4_commutative:1394; V7M: @ %bb.0:1395; V7M-NEXT: mov.w r3, #-11396; V7M-NEXT: lsrs r0, r11397; V7M-NEXT: lsl.w r2, r3, r21398; V7M-NEXT: bics r0, r21399; V7M-NEXT: bx lr1400;1401; V7A-LABEL: bextr32_b4_commutative:1402; V7A: @ %bb.0:1403; V7A-NEXT: lsr r0, r0, r11404; V7A-NEXT: mvn r1, #01405; V7A-NEXT: bic r0, r0, r1, lsl r21406; V7A-NEXT: bx lr1407;1408; V7A-T-LABEL: bextr32_b4_commutative:1409; V7A-T: @ %bb.0:1410; V7A-T-NEXT: mov.w r3, #-11411; V7A-T-NEXT: lsrs r0, r11412; V7A-T-NEXT: lsl.w r2, r3, r21413; V7A-T-NEXT: bics r0, r21414; V7A-T-NEXT: bx lr1415;1416; V6M-LABEL: bextr32_b4_commutative:1417; V6M: @ %bb.0:1418; V6M-NEXT: lsrs r0, r11419; V6M-NEXT: movs r1, #01420; V6M-NEXT: mvns r1, r11421; V6M-NEXT: lsls r1, r21422; V6M-NEXT: bics r0, r11423; V6M-NEXT: bx lr1424 %shifted = lshr i32 %val, %numskipbits1425 %notmask = shl i32 -1, %numlowbits1426 %mask = xor i32 %notmask, -11427 %masked = and i32 %shifted, %mask ; swapped order1428 ret i32 %masked1429}1430 1431; 64-bit1432 1433define i64 @bextr64_b0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {1434; V7M-LABEL: bextr64_b0:1435; V7M: @ %bb.0:1436; V7M-NEXT: .save {r7, lr}1437; V7M-NEXT: push {r7, lr}1438; V7M-NEXT: rsb.w r3, r2, #321439; V7M-NEXT: lsrs r0, r21440; V7M-NEXT: ldr.w r12, [sp, #8]1441; V7M-NEXT: lsl.w r3, r1, r31442; V7M-NEXT: orrs r0, r31443; V7M-NEXT: subs.w r3, r2, #321444; V7M-NEXT: it pl1445; V7M-NEXT: lsrpl.w r0, r1, r31446; V7M-NEXT: lsr.w r1, r1, r21447; V7M-NEXT: mov.w r2, #-11448; V7M-NEXT: it pl1449; V7M-NEXT: movpl r1, #01450; V7M-NEXT: lsl.w r3, r2, r121451; V7M-NEXT: subs.w lr, r12, #321452; V7M-NEXT: it pl1453; V7M-NEXT: lslpl.w r2, r2, lr1454; V7M-NEXT: it pl1455; V7M-NEXT: movpl r3, #01456; V7M-NEXT: bics r1, r21457; V7M-NEXT: bics r0, r31458; V7M-NEXT: pop {r7, pc}1459;1460; V7A-LABEL: bextr64_b0:1461; V7A: @ %bb.0:1462; V7A-NEXT: .save {r11, lr}1463; V7A-NEXT: push {r11, lr}1464; V7A-NEXT: rsb r3, r2, #321465; V7A-NEXT: lsr r0, r0, r21466; V7A-NEXT: ldr r12, [sp, #8]1467; V7A-NEXT: orr r0, r0, r1, lsl r31468; V7A-NEXT: subs r3, r2, #321469; V7A-NEXT: lsrpl r0, r1, r31470; V7A-NEXT: lsr r1, r1, r21471; V7A-NEXT: movwpl r1, #01472; V7A-NEXT: mvn r3, #01473; V7A-NEXT: subs lr, r12, #321474; V7A-NEXT: lsl r2, r3, r121475; V7A-NEXT: movwpl r2, #01476; V7A-NEXT: bic r0, r0, r21477; V7A-NEXT: lslpl r3, r3, lr1478; V7A-NEXT: bic r1, r1, r31479; V7A-NEXT: pop {r11, pc}1480;1481; V7A-T-LABEL: bextr64_b0:1482; V7A-T: @ %bb.0:1483; V7A-T-NEXT: .save {r4, r5, r7, lr}1484; V7A-T-NEXT: push {r4, r5, r7, lr}1485; V7A-T-NEXT: rsb.w r3, r2, #321486; V7A-T-NEXT: ldr.w r12, [sp, #16]1487; V7A-T-NEXT: lsrs r0, r21488; V7A-T-NEXT: lsl.w r3, r1, r31489; V7A-T-NEXT: orr.w r5, r0, r31490; V7A-T-NEXT: mov.w r3, #-11491; V7A-T-NEXT: subs.w lr, r12, #321492; V7A-T-NEXT: lsl.w r0, r3, r121493; V7A-T-NEXT: itt pl1494; V7A-T-NEXT: lslpl.w r3, r3, lr1495; V7A-T-NEXT: movpl r0, #01496; V7A-T-NEXT: subs.w r4, r2, #321497; V7A-T-NEXT: it pl1498; V7A-T-NEXT: lsrpl.w r5, r1, r41499; V7A-T-NEXT: lsr.w r1, r1, r21500; V7A-T-NEXT: it pl1501; V7A-T-NEXT: movpl r1, #01502; V7A-T-NEXT: bic.w r0, r5, r01503; V7A-T-NEXT: bics r1, r31504; V7A-T-NEXT: pop {r4, r5, r7, pc}1505;1506; V6M-LABEL: bextr64_b0:1507; V6M: @ %bb.0:1508; V6M-NEXT: .save {r4, r5, r7, lr}1509; V6M-NEXT: push {r4, r5, r7, lr}1510; V6M-NEXT: bl __aeabi_llsr1511; V6M-NEXT: mov r4, r01512; V6M-NEXT: mov r5, r11513; V6M-NEXT: movs r0, #01514; V6M-NEXT: mvns r0, r01515; V6M-NEXT: ldr r2, [sp, #16]1516; V6M-NEXT: mov r1, r01517; V6M-NEXT: bl __aeabi_llsl1518; V6M-NEXT: bics r4, r01519; V6M-NEXT: bics r5, r11520; V6M-NEXT: mov r0, r41521; V6M-NEXT: mov r1, r51522; V6M-NEXT: pop {r4, r5, r7, pc}1523 %shifted = lshr i64 %val, %numskipbits1524 %notmask = shl i64 -1, %numlowbits1525 %mask = xor i64 %notmask, -11526 %masked = and i64 %mask, %shifted1527 ret i64 %masked1528}1529 1530define i64 @bextr64_b1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {1531; V7M-LABEL: bextr64_b1_indexzext:1532; V7M: @ %bb.0:1533; V7M-NEXT: lsr.w r12, r0, r21534; V7M-NEXT: rsb.w r0, r2, #321535; V7M-NEXT: lsl.w r0, r1, r01536; V7M-NEXT: orr.w r12, r12, r01537; V7M-NEXT: subs.w r0, r2, #321538; V7M-NEXT: it pl1539; V7M-NEXT: lsrpl.w r12, r1, r01540; V7M-NEXT: lsr.w r0, r1, r21541; V7M-NEXT: mov.w r2, #-11542; V7M-NEXT: it pl1543; V7M-NEXT: movpl r0, #01544; V7M-NEXT: subs.w r1, r3, #321545; V7M-NEXT: lsl.w r3, r2, r31546; V7M-NEXT: it pl1547; V7M-NEXT: lslpl r2, r11548; V7M-NEXT: bic.w r1, r0, r21549; V7M-NEXT: it pl1550; V7M-NEXT: movpl r3, #01551; V7M-NEXT: bic.w r0, r12, r31552; V7M-NEXT: bx lr1553;1554; V7A-LABEL: bextr64_b1_indexzext:1555; V7A: @ %bb.0:1556; V7A-NEXT: lsr r12, r0, r21557; V7A-NEXT: rsb r0, r2, #321558; V7A-NEXT: orr r12, r12, r1, lsl r01559; V7A-NEXT: subs r0, r2, #321560; V7A-NEXT: lsrpl r12, r1, r01561; V7A-NEXT: lsr r0, r1, r21562; V7A-NEXT: movwpl r0, #01563; V7A-NEXT: subs r1, r3, #321564; V7A-NEXT: mvn r2, #01565; V7A-NEXT: lsl r3, r2, r31566; V7A-NEXT: lslpl r2, r2, r11567; V7A-NEXT: bic r1, r0, r21568; V7A-NEXT: movwpl r3, #01569; V7A-NEXT: bic r0, r12, r31570; V7A-NEXT: bx lr1571;1572; V7A-T-LABEL: bextr64_b1_indexzext:1573; V7A-T: @ %bb.0:1574; V7A-T-NEXT: lsr.w r12, r0, r21575; V7A-T-NEXT: rsb.w r0, r2, #321576; V7A-T-NEXT: lsl.w r0, r1, r01577; V7A-T-NEXT: orr.w r12, r12, r01578; V7A-T-NEXT: subs.w r0, r2, #321579; V7A-T-NEXT: it pl1580; V7A-T-NEXT: lsrpl.w r12, r1, r01581; V7A-T-NEXT: lsr.w r0, r1, r21582; V7A-T-NEXT: mov.w r2, #-11583; V7A-T-NEXT: it pl1584; V7A-T-NEXT: movpl r0, #01585; V7A-T-NEXT: subs.w r1, r3, #321586; V7A-T-NEXT: lsl.w r3, r2, r31587; V7A-T-NEXT: it pl1588; V7A-T-NEXT: lslpl r2, r11589; V7A-T-NEXT: bic.w r1, r0, r21590; V7A-T-NEXT: it pl1591; V7A-T-NEXT: movpl r3, #01592; V7A-T-NEXT: bic.w r0, r12, r31593; V7A-T-NEXT: bx lr1594;1595; V6M-LABEL: bextr64_b1_indexzext:1596; V6M: @ %bb.0:1597; V6M-NEXT: .save {r4, r5, r6, lr}1598; V6M-NEXT: push {r4, r5, r6, lr}1599; V6M-NEXT: mov r4, r31600; V6M-NEXT: bl __aeabi_llsr1601; V6M-NEXT: mov r5, r01602; V6M-NEXT: mov r6, r11603; V6M-NEXT: movs r0, #01604; V6M-NEXT: mvns r0, r01605; V6M-NEXT: mov r1, r01606; V6M-NEXT: mov r2, r41607; V6M-NEXT: bl __aeabi_llsl1608; V6M-NEXT: bics r5, r01609; V6M-NEXT: bics r6, r11610; V6M-NEXT: mov r0, r51611; V6M-NEXT: mov r1, r61612; V6M-NEXT: pop {r4, r5, r6, pc}1613 %skip = zext i8 %numskipbits to i641614 %shifted = lshr i64 %val, %skip1615 %conv = zext i8 %numlowbits to i641616 %notmask = shl i64 -1, %conv1617 %mask = xor i64 %notmask, -11618 %masked = and i64 %mask, %shifted1619 ret i64 %masked1620}1621 1622define i64 @bextr64_b2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {1623; V7M-LABEL: bextr64_b2_load:1624; V7M: @ %bb.0:1625; V7M-NEXT: .save {r7, lr}1626; V7M-NEXT: push {r7, lr}1627; V7M-NEXT: ldrd r0, r3, [r0]1628; V7M-NEXT: rsb.w r1, r2, #321629; V7M-NEXT: ldr.w r12, [sp, #8]1630; V7M-NEXT: lsl.w r1, r3, r11631; V7M-NEXT: lsrs r0, r21632; V7M-NEXT: orrs r0, r11633; V7M-NEXT: subs.w r1, r2, #321634; V7M-NEXT: it pl1635; V7M-NEXT: lsrpl.w r0, r3, r11636; V7M-NEXT: lsr.w r1, r3, r21637; V7M-NEXT: mov.w r2, #-11638; V7M-NEXT: it pl1639; V7M-NEXT: movpl r1, #01640; V7M-NEXT: lsl.w r3, r2, r121641; V7M-NEXT: subs.w lr, r12, #321642; V7M-NEXT: it pl1643; V7M-NEXT: lslpl.w r2, r2, lr1644; V7M-NEXT: it pl1645; V7M-NEXT: movpl r3, #01646; V7M-NEXT: bics r1, r21647; V7M-NEXT: bics r0, r31648; V7M-NEXT: pop {r7, pc}1649;1650; V7A-LABEL: bextr64_b2_load:1651; V7A: @ %bb.0:1652; V7A-NEXT: .save {r11, lr}1653; V7A-NEXT: push {r11, lr}1654; V7A-NEXT: ldrd r0, r1, [r0]1655; V7A-NEXT: rsb r3, r2, #321656; V7A-NEXT: ldr r12, [sp, #8]1657; V7A-NEXT: lsr r0, r0, r21658; V7A-NEXT: orr r0, r0, r1, lsl r31659; V7A-NEXT: subs r3, r2, #321660; V7A-NEXT: lsrpl r0, r1, r31661; V7A-NEXT: lsr r1, r1, r21662; V7A-NEXT: movwpl r1, #01663; V7A-NEXT: mvn r3, #01664; V7A-NEXT: subs lr, r12, #321665; V7A-NEXT: lsl r2, r3, r121666; V7A-NEXT: movwpl r2, #01667; V7A-NEXT: bic r0, r0, r21668; V7A-NEXT: lslpl r3, r3, lr1669; V7A-NEXT: bic r1, r1, r31670; V7A-NEXT: pop {r11, pc}1671;1672; V7A-T-LABEL: bextr64_b2_load:1673; V7A-T: @ %bb.0:1674; V7A-T-NEXT: .save {r7, lr}1675; V7A-T-NEXT: push {r7, lr}1676; V7A-T-NEXT: ldrd r0, r3, [r0]1677; V7A-T-NEXT: rsb.w r1, r2, #321678; V7A-T-NEXT: ldr.w r12, [sp, #8]1679; V7A-T-NEXT: lsl.w r1, r3, r11680; V7A-T-NEXT: lsrs r0, r21681; V7A-T-NEXT: orrs r0, r11682; V7A-T-NEXT: subs.w r1, r2, #321683; V7A-T-NEXT: it pl1684; V7A-T-NEXT: lsrpl.w r0, r3, r11685; V7A-T-NEXT: lsr.w r1, r3, r21686; V7A-T-NEXT: mov.w r3, #-11687; V7A-T-NEXT: it pl1688; V7A-T-NEXT: movpl r1, #01689; V7A-T-NEXT: lsl.w r2, r3, r121690; V7A-T-NEXT: subs.w lr, r12, #321691; V7A-T-NEXT: it pl1692; V7A-T-NEXT: lslpl.w r3, r3, lr1693; V7A-T-NEXT: it pl1694; V7A-T-NEXT: movpl r2, #01695; V7A-T-NEXT: bics r1, r31696; V7A-T-NEXT: bics r0, r21697; V7A-T-NEXT: pop {r7, pc}1698;1699; V6M-LABEL: bextr64_b2_load:1700; V6M: @ %bb.0:1701; V6M-NEXT: .save {r4, r5, r7, lr}1702; V6M-NEXT: push {r4, r5, r7, lr}1703; V6M-NEXT: ldr r3, [r0]1704; V6M-NEXT: ldr r1, [r0, #4]1705; V6M-NEXT: mov r0, r31706; V6M-NEXT: bl __aeabi_llsr1707; V6M-NEXT: mov r4, r01708; V6M-NEXT: mov r5, r11709; V6M-NEXT: movs r0, #01710; V6M-NEXT: mvns r0, r01711; V6M-NEXT: ldr r2, [sp, #16]1712; V6M-NEXT: mov r1, r01713; V6M-NEXT: bl __aeabi_llsl1714; V6M-NEXT: bics r4, r01715; V6M-NEXT: bics r5, r11716; V6M-NEXT: mov r0, r41717; V6M-NEXT: mov r1, r51718; V6M-NEXT: pop {r4, r5, r7, pc}1719 %val = load i64, ptr %w1720 %shifted = lshr i64 %val, %numskipbits1721 %notmask = shl i64 -1, %numlowbits1722 %mask = xor i64 %notmask, -11723 %masked = and i64 %mask, %shifted1724 ret i64 %masked1725}1726 1727define i64 @bextr64_b3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {1728; V7M-LABEL: bextr64_b3_load_indexzext:1729; V7M: @ %bb.0:1730; V7M-NEXT: .save {r7, lr}1731; V7M-NEXT: push {r7, lr}1732; V7M-NEXT: ldrd r12, r0, [r0]1733; V7M-NEXT: rsb.w r3, r1, #321734; V7M-NEXT: lsl.w lr, r0, r31735; V7M-NEXT: lsr.w r3, r12, r11736; V7M-NEXT: orr.w r12, r3, lr1737; V7M-NEXT: subs.w r3, r1, #321738; V7M-NEXT: it pl1739; V7M-NEXT: lsrpl.w r12, r0, r31740; V7M-NEXT: lsr.w r0, r0, r11741; V7M-NEXT: mov.w r3, #-11742; V7M-NEXT: it pl1743; V7M-NEXT: movpl r0, #01744; V7M-NEXT: subs.w r1, r2, #321745; V7M-NEXT: lsl.w r2, r3, r21746; V7M-NEXT: it pl1747; V7M-NEXT: lslpl r3, r11748; V7M-NEXT: bic.w r1, r0, r31749; V7M-NEXT: it pl1750; V7M-NEXT: movpl r2, #01751; V7M-NEXT: bic.w r0, r12, r21752; V7M-NEXT: pop {r7, pc}1753;1754; V7A-LABEL: bextr64_b3_load_indexzext:1755; V7A: @ %bb.0:1756; V7A-NEXT: ldm r0, {r0, r3}1757; V7A-NEXT: lsr r12, r0, r11758; V7A-NEXT: rsb r0, r1, #321759; V7A-NEXT: orr r12, r12, r3, lsl r01760; V7A-NEXT: subs r0, r1, #321761; V7A-NEXT: lsrpl r12, r3, r01762; V7A-NEXT: lsr r0, r3, r11763; V7A-NEXT: movwpl r0, #01764; V7A-NEXT: subs r1, r2, #321765; V7A-NEXT: mvn r3, #01766; V7A-NEXT: lsl r2, r3, r21767; V7A-NEXT: lslpl r3, r3, r11768; V7A-NEXT: bic r1, r0, r31769; V7A-NEXT: movwpl r2, #01770; V7A-NEXT: bic r0, r12, r21771; V7A-NEXT: bx lr1772;1773; V7A-T-LABEL: bextr64_b3_load_indexzext:1774; V7A-T: @ %bb.0:1775; V7A-T-NEXT: .save {r7, lr}1776; V7A-T-NEXT: push {r7, lr}1777; V7A-T-NEXT: ldrd r12, r3, [r0]1778; V7A-T-NEXT: rsb.w r0, r1, #321779; V7A-T-NEXT: lsl.w lr, r3, r01780; V7A-T-NEXT: lsr.w r0, r12, r11781; V7A-T-NEXT: orr.w r12, r0, lr1782; V7A-T-NEXT: subs.w r0, r1, #321783; V7A-T-NEXT: it pl1784; V7A-T-NEXT: lsrpl.w r12, r3, r01785; V7A-T-NEXT: lsr.w r0, r3, r11786; V7A-T-NEXT: mov.w r3, #-11787; V7A-T-NEXT: it pl1788; V7A-T-NEXT: movpl r0, #01789; V7A-T-NEXT: subs.w r1, r2, #321790; V7A-T-NEXT: lsl.w r2, r3, r21791; V7A-T-NEXT: it pl1792; V7A-T-NEXT: lslpl r3, r11793; V7A-T-NEXT: bic.w r1, r0, r31794; V7A-T-NEXT: it pl1795; V7A-T-NEXT: movpl r2, #01796; V7A-T-NEXT: bic.w r0, r12, r21797; V7A-T-NEXT: pop {r7, pc}1798;1799; V6M-LABEL: bextr64_b3_load_indexzext:1800; V6M: @ %bb.0:1801; V6M-NEXT: .save {r4, r5, r6, lr}1802; V6M-NEXT: push {r4, r5, r6, lr}1803; V6M-NEXT: mov r4, r21804; V6M-NEXT: mov r2, r11805; V6M-NEXT: ldr r3, [r0]1806; V6M-NEXT: ldr r1, [r0, #4]1807; V6M-NEXT: mov r0, r31808; V6M-NEXT: bl __aeabi_llsr1809; V6M-NEXT: mov r5, r01810; V6M-NEXT: mov r6, r11811; V6M-NEXT: movs r0, #01812; V6M-NEXT: mvns r0, r01813; V6M-NEXT: mov r1, r01814; V6M-NEXT: mov r2, r41815; V6M-NEXT: bl __aeabi_llsl1816; V6M-NEXT: bics r5, r01817; V6M-NEXT: bics r6, r11818; V6M-NEXT: mov r0, r51819; V6M-NEXT: mov r1, r61820; V6M-NEXT: pop {r4, r5, r6, pc}1821 %val = load i64, ptr %w1822 %skip = zext i8 %numskipbits to i641823 %shifted = lshr i64 %val, %skip1824 %conv = zext i8 %numlowbits to i641825 %notmask = shl i64 -1, %conv1826 %mask = xor i64 %notmask, -11827 %masked = and i64 %mask, %shifted1828 ret i64 %masked1829}1830 1831define i64 @bextr64_b4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {1832; V7M-LABEL: bextr64_b4_commutative:1833; V7M: @ %bb.0:1834; V7M-NEXT: .save {r7, lr}1835; V7M-NEXT: push {r7, lr}1836; V7M-NEXT: rsb.w r3, r2, #321837; V7M-NEXT: lsrs r0, r21838; V7M-NEXT: ldr.w r12, [sp, #8]1839; V7M-NEXT: lsl.w r3, r1, r31840; V7M-NEXT: orrs r0, r31841; V7M-NEXT: subs.w r3, r2, #321842; V7M-NEXT: it pl1843; V7M-NEXT: lsrpl.w r0, r1, r31844; V7M-NEXT: lsr.w r1, r1, r21845; V7M-NEXT: mov.w r2, #-11846; V7M-NEXT: it pl1847; V7M-NEXT: movpl r1, #01848; V7M-NEXT: lsl.w r3, r2, r121849; V7M-NEXT: subs.w lr, r12, #321850; V7M-NEXT: it pl1851; V7M-NEXT: lslpl.w r2, r2, lr1852; V7M-NEXT: it pl1853; V7M-NEXT: movpl r3, #01854; V7M-NEXT: bics r1, r21855; V7M-NEXT: bics r0, r31856; V7M-NEXT: pop {r7, pc}1857;1858; V7A-LABEL: bextr64_b4_commutative:1859; V7A: @ %bb.0:1860; V7A-NEXT: .save {r11, lr}1861; V7A-NEXT: push {r11, lr}1862; V7A-NEXT: rsb r3, r2, #321863; V7A-NEXT: lsr r0, r0, r21864; V7A-NEXT: ldr r12, [sp, #8]1865; V7A-NEXT: orr r0, r0, r1, lsl r31866; V7A-NEXT: subs r3, r2, #321867; V7A-NEXT: lsrpl r0, r1, r31868; V7A-NEXT: lsr r1, r1, r21869; V7A-NEXT: movwpl r1, #01870; V7A-NEXT: mvn r3, #01871; V7A-NEXT: subs lr, r12, #321872; V7A-NEXT: lsl r2, r3, r121873; V7A-NEXT: movwpl r2, #01874; V7A-NEXT: bic r0, r0, r21875; V7A-NEXT: lslpl r3, r3, lr1876; V7A-NEXT: bic r1, r1, r31877; V7A-NEXT: pop {r11, pc}1878;1879; V7A-T-LABEL: bextr64_b4_commutative:1880; V7A-T: @ %bb.0:1881; V7A-T-NEXT: .save {r4, r5, r7, lr}1882; V7A-T-NEXT: push {r4, r5, r7, lr}1883; V7A-T-NEXT: rsb.w r3, r2, #321884; V7A-T-NEXT: ldr.w r12, [sp, #16]1885; V7A-T-NEXT: lsrs r0, r21886; V7A-T-NEXT: lsl.w r3, r1, r31887; V7A-T-NEXT: orr.w r5, r0, r31888; V7A-T-NEXT: mov.w r3, #-11889; V7A-T-NEXT: subs.w lr, r12, #321890; V7A-T-NEXT: lsl.w r0, r3, r121891; V7A-T-NEXT: itt pl1892; V7A-T-NEXT: lslpl.w r3, r3, lr1893; V7A-T-NEXT: movpl r0, #01894; V7A-T-NEXT: subs.w r4, r2, #321895; V7A-T-NEXT: it pl1896; V7A-T-NEXT: lsrpl.w r5, r1, r41897; V7A-T-NEXT: lsr.w r1, r1, r21898; V7A-T-NEXT: it pl1899; V7A-T-NEXT: movpl r1, #01900; V7A-T-NEXT: bic.w r0, r5, r01901; V7A-T-NEXT: bics r1, r31902; V7A-T-NEXT: pop {r4, r5, r7, pc}1903;1904; V6M-LABEL: bextr64_b4_commutative:1905; V6M: @ %bb.0:1906; V6M-NEXT: .save {r4, r5, r7, lr}1907; V6M-NEXT: push {r4, r5, r7, lr}1908; V6M-NEXT: bl __aeabi_llsr1909; V6M-NEXT: mov r4, r01910; V6M-NEXT: mov r5, r11911; V6M-NEXT: movs r0, #01912; V6M-NEXT: mvns r0, r01913; V6M-NEXT: ldr r2, [sp, #16]1914; V6M-NEXT: mov r1, r01915; V6M-NEXT: bl __aeabi_llsl1916; V6M-NEXT: bics r4, r01917; V6M-NEXT: bics r5, r11918; V6M-NEXT: mov r0, r41919; V6M-NEXT: mov r1, r51920; V6M-NEXT: pop {r4, r5, r7, pc}1921 %shifted = lshr i64 %val, %numskipbits1922 %notmask = shl i64 -1, %numlowbits1923 %mask = xor i64 %notmask, -11924 %masked = and i64 %shifted, %mask ; swapped order1925 ret i64 %masked1926}1927 1928; 64-bit, but with 32-bit output1929 1930; Everything done in 64-bit, truncation happens last.1931define i32 @bextr64_32_b0(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {1932; V7M-LABEL: bextr64_32_b0:1933; V7M: @ %bb.0:1934; V7M-NEXT: rsb.w r3, r2, #321935; V7M-NEXT: lsrs r0, r21936; V7M-NEXT: subs r2, #321937; V7M-NEXT: lsl.w r3, r1, r31938; V7M-NEXT: orr.w r0, r0, r31939; V7M-NEXT: it pl1940; V7M-NEXT: lsrpl.w r0, r1, r21941; V7M-NEXT: ldrb.w r1, [sp]1942; V7M-NEXT: mov.w r2, #-11943; V7M-NEXT: lsls r2, r11944; V7M-NEXT: subs r1, #321945; V7M-NEXT: it pl1946; V7M-NEXT: movpl r2, #01947; V7M-NEXT: bics r0, r21948; V7M-NEXT: bx lr1949;1950; V7A-LABEL: bextr64_32_b0:1951; V7A: @ %bb.0:1952; V7A-NEXT: rsb r3, r2, #321953; V7A-NEXT: lsr r0, r0, r21954; V7A-NEXT: ldrb r12, [sp]1955; V7A-NEXT: subs r2, r2, #321956; V7A-NEXT: orr r0, r0, r1, lsl r31957; V7A-NEXT: lsrpl r0, r1, r21958; V7A-NEXT: mvn r1, #01959; V7A-NEXT: lsl r1, r1, r121960; V7A-NEXT: subs r2, r12, #321961; V7A-NEXT: movwpl r1, #01962; V7A-NEXT: bic r0, r0, r11963; V7A-NEXT: bx lr1964;1965; V7A-T-LABEL: bextr64_32_b0:1966; V7A-T: @ %bb.0:1967; V7A-T-NEXT: lsr.w r12, r0, r21968; V7A-T-NEXT: rsb.w r0, r2, #321969; V7A-T-NEXT: ldrb.w r3, [sp]1970; V7A-T-NEXT: subs r2, #321971; V7A-T-NEXT: lsl.w r0, r1, r01972; V7A-T-NEXT: orr.w r0, r0, r121973; V7A-T-NEXT: it pl1974; V7A-T-NEXT: lsrpl.w r0, r1, r21975; V7A-T-NEXT: mov.w r1, #-11976; V7A-T-NEXT: lsls r1, r31977; V7A-T-NEXT: subs.w r2, r3, #321978; V7A-T-NEXT: it pl1979; V7A-T-NEXT: movpl r1, #01980; V7A-T-NEXT: bics r0, r11981; V7A-T-NEXT: bx lr1982;1983; V6M-LABEL: bextr64_32_b0:1984; V6M: @ %bb.0:1985; V6M-NEXT: .save {r4, lr}1986; V6M-NEXT: push {r4, lr}1987; V6M-NEXT: bl __aeabi_llsr1988; V6M-NEXT: mov r4, r01989; V6M-NEXT: movs r0, #01990; V6M-NEXT: mvns r0, r01991; V6M-NEXT: add r1, sp, #81992; V6M-NEXT: ldrb r2, [r1]1993; V6M-NEXT: mov r1, r01994; V6M-NEXT: bl __aeabi_llsl1995; V6M-NEXT: bics r4, r01996; V6M-NEXT: mov r0, r41997; V6M-NEXT: pop {r4, pc}1998 %shiftedval = lshr i64 %val, %numskipbits1999 %widenumlowbits = zext i8 %numlowbits to i642000 %notmask = shl nsw i64 -1, %widenumlowbits2001 %mask = xor i64 %notmask, -12002 %wideres = and i64 %shiftedval, %mask2003 %res = trunc i64 %wideres to i322004 ret i32 %res2005}2006 2007; Shifting happens in 64-bit, then truncation. Masking is 32-bit.2008define i32 @bextr64_32_b1(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {2009; V7M-LABEL: bextr64_32_b1:2010; V7M: @ %bb.0:2011; V7M-NEXT: rsb.w r3, r2, #322012; V7M-NEXT: lsrs r0, r22013; V7M-NEXT: subs r2, #322014; V7M-NEXT: lsl.w r3, r1, r32015; V7M-NEXT: orr.w r0, r0, r32016; V7M-NEXT: it pl2017; V7M-NEXT: lsrpl.w r0, r1, r22018; V7M-NEXT: ldrb.w r1, [sp]2019; V7M-NEXT: mov.w r2, #-12020; V7M-NEXT: lsl.w r1, r2, r12021; V7M-NEXT: bics r0, r12022; V7M-NEXT: bx lr2023;2024; V7A-LABEL: bextr64_32_b1:2025; V7A: @ %bb.0:2026; V7A-NEXT: rsb r3, r2, #322027; V7A-NEXT: lsr r0, r0, r22028; V7A-NEXT: ldrb r12, [sp]2029; V7A-NEXT: subs r2, r2, #322030; V7A-NEXT: orr r0, r0, r1, lsl r32031; V7A-NEXT: lsrpl r0, r1, r22032; V7A-NEXT: mvn r1, #02033; V7A-NEXT: bic r0, r0, r1, lsl r122034; V7A-NEXT: bx lr2035;2036; V7A-T-LABEL: bextr64_32_b1:2037; V7A-T: @ %bb.0:2038; V7A-T-NEXT: rsb.w r3, r2, #322039; V7A-T-NEXT: lsrs r0, r22040; V7A-T-NEXT: ldrb.w r12, [sp]2041; V7A-T-NEXT: subs r2, #322042; V7A-T-NEXT: lsl.w r3, r1, r32043; V7A-T-NEXT: orr.w r0, r0, r32044; V7A-T-NEXT: it pl2045; V7A-T-NEXT: lsrpl.w r0, r1, r22046; V7A-T-NEXT: mov.w r1, #-12047; V7A-T-NEXT: lsl.w r1, r1, r122048; V7A-T-NEXT: bics r0, r12049; V7A-T-NEXT: bx lr2050;2051; V6M-LABEL: bextr64_32_b1:2052; V6M: @ %bb.0:2053; V6M-NEXT: .save {r7, lr}2054; V6M-NEXT: push {r7, lr}2055; V6M-NEXT: bl __aeabi_llsr2056; V6M-NEXT: add r1, sp, #82057; V6M-NEXT: ldrb r1, [r1]2058; V6M-NEXT: movs r2, #02059; V6M-NEXT: mvns r2, r22060; V6M-NEXT: lsls r2, r12061; V6M-NEXT: bics r0, r22062; V6M-NEXT: pop {r7, pc}2063 %shiftedval = lshr i64 %val, %numskipbits2064 %truncshiftedval = trunc i64 %shiftedval to i322065 %widenumlowbits = zext i8 %numlowbits to i322066 %notmask = shl nsw i32 -1, %widenumlowbits2067 %mask = xor i32 %notmask, -12068 %res = and i32 %truncshiftedval, %mask2069 ret i32 %res2070}2071 2072; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.2073; Masking is 64-bit. Then truncation.2074define i32 @bextr64_32_b2(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {2075; V7M-LABEL: bextr64_32_b2:2076; V7M: @ %bb.0:2077; V7M-NEXT: rsb.w r3, r2, #322078; V7M-NEXT: lsrs r0, r22079; V7M-NEXT: subs r2, #322080; V7M-NEXT: lsl.w r3, r1, r32081; V7M-NEXT: orr.w r0, r0, r32082; V7M-NEXT: it pl2083; V7M-NEXT: lsrpl.w r0, r1, r22084; V7M-NEXT: ldrb.w r1, [sp]2085; V7M-NEXT: mov.w r2, #-12086; V7M-NEXT: lsl.w r1, r2, r12087; V7M-NEXT: bics r0, r12088; V7M-NEXT: bx lr2089;2090; V7A-LABEL: bextr64_32_b2:2091; V7A: @ %bb.0:2092; V7A-NEXT: rsb r3, r2, #322093; V7A-NEXT: lsr r0, r0, r22094; V7A-NEXT: ldrb r12, [sp]2095; V7A-NEXT: subs r2, r2, #322096; V7A-NEXT: orr r0, r0, r1, lsl r32097; V7A-NEXT: lsrpl r0, r1, r22098; V7A-NEXT: mvn r1, #02099; V7A-NEXT: bic r0, r0, r1, lsl r122100; V7A-NEXT: bx lr2101;2102; V7A-T-LABEL: bextr64_32_b2:2103; V7A-T: @ %bb.0:2104; V7A-T-NEXT: rsb.w r3, r2, #322105; V7A-T-NEXT: lsrs r0, r22106; V7A-T-NEXT: ldrb.w r12, [sp]2107; V7A-T-NEXT: subs r2, #322108; V7A-T-NEXT: lsl.w r3, r1, r32109; V7A-T-NEXT: orr.w r0, r0, r32110; V7A-T-NEXT: it pl2111; V7A-T-NEXT: lsrpl.w r0, r1, r22112; V7A-T-NEXT: mov.w r1, #-12113; V7A-T-NEXT: lsl.w r1, r1, r122114; V7A-T-NEXT: bics r0, r12115; V7A-T-NEXT: bx lr2116;2117; V6M-LABEL: bextr64_32_b2:2118; V6M: @ %bb.0:2119; V6M-NEXT: .save {r7, lr}2120; V6M-NEXT: push {r7, lr}2121; V6M-NEXT: bl __aeabi_llsr2122; V6M-NEXT: add r1, sp, #82123; V6M-NEXT: ldrb r1, [r1]2124; V6M-NEXT: movs r2, #02125; V6M-NEXT: mvns r2, r22126; V6M-NEXT: lsls r2, r12127; V6M-NEXT: bics r0, r22128; V6M-NEXT: pop {r7, pc}2129 %shiftedval = lshr i64 %val, %numskipbits2130 %widenumlowbits = zext i8 %numlowbits to i322131 %notmask = shl nsw i32 -1, %widenumlowbits2132 %mask = xor i32 %notmask, -12133 %zextmask = zext i32 %mask to i642134 %wideres = and i64 %shiftedval, %zextmask2135 %res = trunc i64 %wideres to i322136 ret i32 %res2137}2138 2139; ---------------------------------------------------------------------------- ;2140; Pattern c. 32-bit2141; ---------------------------------------------------------------------------- ;2142 2143define i32 @bextr32_c0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {2144; V7M-LABEL: bextr32_c0:2145; V7M: @ %bb.0:2146; V7M-NEXT: lsrs r0, r12147; V7M-NEXT: rsb.w r1, r2, #322148; V7M-NEXT: lsls r0, r12149; V7M-NEXT: lsrs r0, r12150; V7M-NEXT: bx lr2151;2152; V7A-LABEL: bextr32_c0:2153; V7A: @ %bb.0:2154; V7A-NEXT: lsr r0, r0, r12155; V7A-NEXT: rsb r1, r2, #322156; V7A-NEXT: lsl r0, r0, r12157; V7A-NEXT: lsr r0, r0, r12158; V7A-NEXT: bx lr2159;2160; V7A-T-LABEL: bextr32_c0:2161; V7A-T: @ %bb.0:2162; V7A-T-NEXT: lsrs r0, r12163; V7A-T-NEXT: rsb.w r1, r2, #322164; V7A-T-NEXT: lsls r0, r12165; V7A-T-NEXT: lsrs r0, r12166; V7A-T-NEXT: bx lr2167;2168; V6M-LABEL: bextr32_c0:2169; V6M: @ %bb.0:2170; V6M-NEXT: movs r3, #322171; V6M-NEXT: subs r2, r3, r22172; V6M-NEXT: lsrs r0, r12173; V6M-NEXT: lsls r0, r22174; V6M-NEXT: lsrs r0, r22175; V6M-NEXT: bx lr2176 %shifted = lshr i32 %val, %numskipbits2177 %numhighbits = sub i32 32, %numlowbits2178 %mask = lshr i32 -1, %numhighbits2179 %masked = and i32 %mask, %shifted2180 ret i32 %masked2181}2182 2183define i32 @bextr32_c1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind {2184; V7M-LABEL: bextr32_c1_indexzext:2185; V7M: @ %bb.0:2186; V7M-NEXT: uxtb r1, r12187; V7M-NEXT: lsrs r0, r12188; V7M-NEXT: rsb.w r1, r2, #322189; V7M-NEXT: uxtb r1, r12190; V7M-NEXT: lsls r0, r12191; V7M-NEXT: lsrs r0, r12192; V7M-NEXT: bx lr2193;2194; V7A-LABEL: bextr32_c1_indexzext:2195; V7A: @ %bb.0:2196; V7A-NEXT: uxtb r1, r12197; V7A-NEXT: lsr r0, r0, r12198; V7A-NEXT: rsb r1, r2, #322199; V7A-NEXT: uxtb r1, r12200; V7A-NEXT: lsl r0, r0, r12201; V7A-NEXT: lsr r0, r0, r12202; V7A-NEXT: bx lr2203;2204; V7A-T-LABEL: bextr32_c1_indexzext:2205; V7A-T: @ %bb.0:2206; V7A-T-NEXT: uxtb r1, r12207; V7A-T-NEXT: lsrs r0, r12208; V7A-T-NEXT: rsb.w r1, r2, #322209; V7A-T-NEXT: uxtb r1, r12210; V7A-T-NEXT: lsls r0, r12211; V7A-T-NEXT: lsrs r0, r12212; V7A-T-NEXT: bx lr2213;2214; V6M-LABEL: bextr32_c1_indexzext:2215; V6M: @ %bb.0:2216; V6M-NEXT: uxtb r1, r12217; V6M-NEXT: lsrs r0, r12218; V6M-NEXT: movs r1, #322219; V6M-NEXT: subs r1, r1, r22220; V6M-NEXT: uxtb r1, r12221; V6M-NEXT: lsls r0, r12222; V6M-NEXT: lsrs r0, r12223; V6M-NEXT: bx lr2224 %skip = zext i8 %numskipbits to i322225 %shifted = lshr i32 %val, %skip2226 %numhighbits = sub i8 32, %numlowbits2227 %sh_prom = zext i8 %numhighbits to i322228 %mask = lshr i32 -1, %sh_prom2229 %masked = and i32 %mask, %shifted2230 ret i32 %masked2231}2232 2233define i32 @bextr32_c2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {2234; V7M-LABEL: bextr32_c2_load:2235; V7M: @ %bb.0:2236; V7M-NEXT: ldr r0, [r0]2237; V7M-NEXT: lsrs r0, r12238; V7M-NEXT: rsb.w r1, r2, #322239; V7M-NEXT: lsls r0, r12240; V7M-NEXT: lsrs r0, r12241; V7M-NEXT: bx lr2242;2243; V7A-LABEL: bextr32_c2_load:2244; V7A: @ %bb.0:2245; V7A-NEXT: ldr r0, [r0]2246; V7A-NEXT: lsr r0, r0, r12247; V7A-NEXT: rsb r1, r2, #322248; V7A-NEXT: lsl r0, r0, r12249; V7A-NEXT: lsr r0, r0, r12250; V7A-NEXT: bx lr2251;2252; V7A-T-LABEL: bextr32_c2_load:2253; V7A-T: @ %bb.0:2254; V7A-T-NEXT: ldr r0, [r0]2255; V7A-T-NEXT: lsrs r0, r12256; V7A-T-NEXT: rsb.w r1, r2, #322257; V7A-T-NEXT: lsls r0, r12258; V7A-T-NEXT: lsrs r0, r12259; V7A-T-NEXT: bx lr2260;2261; V6M-LABEL: bextr32_c2_load:2262; V6M: @ %bb.0:2263; V6M-NEXT: movs r3, #322264; V6M-NEXT: subs r2, r3, r22265; V6M-NEXT: ldr r0, [r0]2266; V6M-NEXT: lsrs r0, r12267; V6M-NEXT: lsls r0, r22268; V6M-NEXT: lsrs r0, r22269; V6M-NEXT: bx lr2270 %val = load i32, ptr %w2271 %shifted = lshr i32 %val, %numskipbits2272 %numhighbits = sub i32 32, %numlowbits2273 %mask = lshr i32 -1, %numhighbits2274 %masked = and i32 %mask, %shifted2275 ret i32 %masked2276}2277 2278define i32 @bextr32_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {2279; V7M-LABEL: bextr32_c3_load_indexzext:2280; V7M: @ %bb.0:2281; V7M-NEXT: ldr r0, [r0]2282; V7M-NEXT: uxtb r1, r12283; V7M-NEXT: lsrs r0, r12284; V7M-NEXT: rsb.w r1, r2, #322285; V7M-NEXT: uxtb r1, r12286; V7M-NEXT: lsls r0, r12287; V7M-NEXT: lsrs r0, r12288; V7M-NEXT: bx lr2289;2290; V7A-LABEL: bextr32_c3_load_indexzext:2291; V7A: @ %bb.0:2292; V7A-NEXT: ldr r0, [r0]2293; V7A-NEXT: uxtb r1, r12294; V7A-NEXT: lsr r0, r0, r12295; V7A-NEXT: rsb r1, r2, #322296; V7A-NEXT: uxtb r1, r12297; V7A-NEXT: lsl r0, r0, r12298; V7A-NEXT: lsr r0, r0, r12299; V7A-NEXT: bx lr2300;2301; V7A-T-LABEL: bextr32_c3_load_indexzext:2302; V7A-T: @ %bb.0:2303; V7A-T-NEXT: ldr r0, [r0]2304; V7A-T-NEXT: uxtb r1, r12305; V7A-T-NEXT: lsrs r0, r12306; V7A-T-NEXT: rsb.w r1, r2, #322307; V7A-T-NEXT: uxtb r1, r12308; V7A-T-NEXT: lsls r0, r12309; V7A-T-NEXT: lsrs r0, r12310; V7A-T-NEXT: bx lr2311;2312; V6M-LABEL: bextr32_c3_load_indexzext:2313; V6M: @ %bb.0:2314; V6M-NEXT: uxtb r1, r12315; V6M-NEXT: ldr r0, [r0]2316; V6M-NEXT: lsrs r0, r12317; V6M-NEXT: movs r1, #322318; V6M-NEXT: subs r1, r1, r22319; V6M-NEXT: uxtb r1, r12320; V6M-NEXT: lsls r0, r12321; V6M-NEXT: lsrs r0, r12322; V6M-NEXT: bx lr2323 %val = load i32, ptr %w2324 %skip = zext i8 %numskipbits to i322325 %shifted = lshr i32 %val, %skip2326 %numhighbits = sub i8 32, %numlowbits2327 %sh_prom = zext i8 %numhighbits to i322328 %mask = lshr i32 -1, %sh_prom2329 %masked = and i32 %mask, %shifted2330 ret i32 %masked2331}2332 2333define i32 @bextr32_c4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {2334; V7M-LABEL: bextr32_c4_commutative:2335; V7M: @ %bb.0:2336; V7M-NEXT: lsrs r0, r12337; V7M-NEXT: rsb.w r1, r2, #322338; V7M-NEXT: lsls r0, r12339; V7M-NEXT: lsrs r0, r12340; V7M-NEXT: bx lr2341;2342; V7A-LABEL: bextr32_c4_commutative:2343; V7A: @ %bb.0:2344; V7A-NEXT: lsr r0, r0, r12345; V7A-NEXT: rsb r1, r2, #322346; V7A-NEXT: lsl r0, r0, r12347; V7A-NEXT: lsr r0, r0, r12348; V7A-NEXT: bx lr2349;2350; V7A-T-LABEL: bextr32_c4_commutative:2351; V7A-T: @ %bb.0:2352; V7A-T-NEXT: lsrs r0, r12353; V7A-T-NEXT: rsb.w r1, r2, #322354; V7A-T-NEXT: lsls r0, r12355; V7A-T-NEXT: lsrs r0, r12356; V7A-T-NEXT: bx lr2357;2358; V6M-LABEL: bextr32_c4_commutative:2359; V6M: @ %bb.0:2360; V6M-NEXT: movs r3, #322361; V6M-NEXT: subs r2, r3, r22362; V6M-NEXT: lsrs r0, r12363; V6M-NEXT: lsls r0, r22364; V6M-NEXT: lsrs r0, r22365; V6M-NEXT: bx lr2366 %shifted = lshr i32 %val, %numskipbits2367 %numhighbits = sub i32 32, %numlowbits2368 %mask = lshr i32 -1, %numhighbits2369 %masked = and i32 %shifted, %mask ; swapped order2370 ret i32 %masked2371}2372 2373; 64-bit2374 2375define i64 @bextr64_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {2376; V7M-LABEL: bextr64_c0:2377; V7M: @ %bb.0:2378; V7M-NEXT: rsb.w r3, r2, #322379; V7M-NEXT: lsrs r0, r22380; V7M-NEXT: ldr.w r12, [sp]2381; V7M-NEXT: lsl.w r3, r1, r32382; V7M-NEXT: orrs r0, r32383; V7M-NEXT: subs.w r3, r2, #322384; V7M-NEXT: it pl2385; V7M-NEXT: lsrpl.w r0, r1, r32386; V7M-NEXT: rsb.w r3, r12, #642387; V7M-NEXT: lsr.w r1, r1, r22388; V7M-NEXT: mov.w r2, #-12389; V7M-NEXT: it pl2390; V7M-NEXT: movpl r1, #02391; V7M-NEXT: lsr.w r3, r2, r32392; V7M-NEXT: rsbs.w r12, r12, #322393; V7M-NEXT: it pl2394; V7M-NEXT: movpl r3, #02395; V7M-NEXT: it pl2396; V7M-NEXT: lsrpl.w r2, r2, r122397; V7M-NEXT: ands r1, r32398; V7M-NEXT: ands r0, r22399; V7M-NEXT: bx lr2400;2401; V7A-LABEL: bextr64_c0:2402; V7A: @ %bb.0:2403; V7A-NEXT: .save {r4, r5, r11, lr}2404; V7A-NEXT: push {r4, r5, r11, lr}2405; V7A-NEXT: ldr r12, [sp, #16]2406; V7A-NEXT: mvn r3, #02407; V7A-NEXT: lsr r5, r1, r22408; V7A-NEXT: lsr r0, r0, r22409; V7A-NEXT: rsb r4, r12, #642410; V7A-NEXT: rsbs lr, r12, #322411; V7A-NEXT: lsr r4, r3, r42412; V7A-NEXT: lsrpl r3, r3, lr2413; V7A-NEXT: movwpl r4, #02414; V7A-NEXT: subs lr, r2, #322415; V7A-NEXT: rsb r2, r2, #322416; V7A-NEXT: movwpl r5, #02417; V7A-NEXT: and r12, r4, r52418; V7A-NEXT: orr r0, r0, r1, lsl r22419; V7A-NEXT: lsrpl r0, r1, lr2420; V7A-NEXT: mov r1, r122421; V7A-NEXT: and r0, r3, r02422; V7A-NEXT: pop {r4, r5, r11, pc}2423;2424; V7A-T-LABEL: bextr64_c0:2425; V7A-T: @ %bb.0:2426; V7A-T-NEXT: .save {r7, lr}2427; V7A-T-NEXT: push {r7, lr}2428; V7A-T-NEXT: rsb.w r3, r2, #322429; V7A-T-NEXT: lsrs r0, r22430; V7A-T-NEXT: ldr.w r12, [sp, #8]2431; V7A-T-NEXT: mov.w lr, #-12432; V7A-T-NEXT: lsl.w r3, r1, r32433; V7A-T-NEXT: orrs r0, r32434; V7A-T-NEXT: subs.w r3, r2, #322435; V7A-T-NEXT: it pl2436; V7A-T-NEXT: lsrpl.w r0, r1, r32437; V7A-T-NEXT: lsr.w r1, r1, r22438; V7A-T-NEXT: mov.w r3, #-12439; V7A-T-NEXT: it pl2440; V7A-T-NEXT: movpl r1, #02441; V7A-T-NEXT: rsbs.w r2, r12, #322442; V7A-T-NEXT: it pl2443; V7A-T-NEXT: lsrpl r3, r22444; V7A-T-NEXT: rsb.w r2, r12, #642445; V7A-T-NEXT: and.w r0, r0, r32446; V7A-T-NEXT: lsr.w r2, lr, r22447; V7A-T-NEXT: it pl2448; V7A-T-NEXT: movpl r2, #02449; V7A-T-NEXT: ands r1, r22450; V7A-T-NEXT: pop {r7, pc}2451;2452; V6M-LABEL: bextr64_c0:2453; V6M: @ %bb.0:2454; V6M-NEXT: .save {r4, r5, r7, lr}2455; V6M-NEXT: push {r4, r5, r7, lr}2456; V6M-NEXT: bl __aeabi_llsr2457; V6M-NEXT: mov r5, r02458; V6M-NEXT: mov r4, r12459; V6M-NEXT: ldr r0, [sp, #16]2460; V6M-NEXT: movs r1, #642461; V6M-NEXT: subs r2, r1, r02462; V6M-NEXT: movs r0, #02463; V6M-NEXT: mvns r0, r02464; V6M-NEXT: mov r1, r02465; V6M-NEXT: bl __aeabi_llsr2466; V6M-NEXT: ands r0, r52467; V6M-NEXT: ands r1, r42468; V6M-NEXT: pop {r4, r5, r7, pc}2469 %shifted = lshr i64 %val, %numskipbits2470 %numhighbits = sub i64 64, %numlowbits2471 %mask = lshr i64 -1, %numhighbits2472 %masked = and i64 %mask, %shifted2473 ret i64 %masked2474}2475 2476define i64 @bextr64_c1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind {2477; V7M-LABEL: bextr64_c1_indexzext:2478; V7M: @ %bb.0:2479; V7M-NEXT: .save {r7, lr}2480; V7M-NEXT: push {r7, lr}2481; V7M-NEXT: uxtb r2, r22482; V7M-NEXT: lsr.w r12, r0, r22483; V7M-NEXT: rsb.w r0, r2, #322484; V7M-NEXT: lsl.w r0, r1, r02485; V7M-NEXT: orr.w r12, r12, r02486; V7M-NEXT: subs.w r0, r2, #322487; V7M-NEXT: it pl2488; V7M-NEXT: lsrpl.w r12, r1, r02489; V7M-NEXT: rsb.w r0, r3, #642490; V7M-NEXT: lsr.w r1, r1, r22491; V7M-NEXT: mov.w r3, #-12492; V7M-NEXT: it pl2493; V7M-NEXT: movpl r1, #02494; V7M-NEXT: uxtb r0, r02495; V7M-NEXT: subs.w lr, r0, #322496; V7M-NEXT: lsr.w r2, r3, r02497; V7M-NEXT: it pl2498; V7M-NEXT: lsrpl.w r3, r3, lr2499; V7M-NEXT: it pl2500; V7M-NEXT: movpl r2, #02501; V7M-NEXT: and.w r0, r3, r122502; V7M-NEXT: ands r1, r22503; V7M-NEXT: pop {r7, pc}2504;2505; V7A-LABEL: bextr64_c1_indexzext:2506; V7A: @ %bb.0:2507; V7A-NEXT: .save {r4, lr}2508; V7A-NEXT: push {r4, lr}2509; V7A-NEXT: uxtb r12, r22510; V7A-NEXT: lsr lr, r0, r122511; V7A-NEXT: rsb r0, r12, #322512; V7A-NEXT: orr r4, lr, r1, lsl r02513; V7A-NEXT: mvn lr, #312514; V7A-NEXT: uxtab r2, lr, r22515; V7A-NEXT: cmp r2, #02516; V7A-NEXT: lsrpl r4, r1, r22517; V7A-NEXT: rsb r2, r3, #642518; V7A-NEXT: lsr r1, r1, r122519; V7A-NEXT: mvn r3, #02520; V7A-NEXT: uxtb r12, r22521; V7A-NEXT: uxtab r2, lr, r22522; V7A-NEXT: movwpl r1, #02523; V7A-NEXT: lsr r0, r3, r122524; V7A-NEXT: cmp r2, #02525; V7A-NEXT: movwpl r0, #02526; V7A-NEXT: and r1, r0, r12527; V7A-NEXT: lsrpl r3, r3, r22528; V7A-NEXT: and r0, r3, r42529; V7A-NEXT: pop {r4, pc}2530;2531; V7A-T-LABEL: bextr64_c1_indexzext:2532; V7A-T: @ %bb.0:2533; V7A-T-NEXT: .save {r4, lr}2534; V7A-T-NEXT: push {r4, lr}2535; V7A-T-NEXT: uxtb.w r12, r22536; V7A-T-NEXT: lsr.w lr, r0, r122537; V7A-T-NEXT: rsb.w r0, r12, #322538; V7A-T-NEXT: lsl.w r0, r1, r02539; V7A-T-NEXT: orr.w r4, lr, r02540; V7A-T-NEXT: mvn lr, #312541; V7A-T-NEXT: uxtab r2, lr, r22542; V7A-T-NEXT: cmp r2, #02543; V7A-T-NEXT: it pl2544; V7A-T-NEXT: lsrpl.w r4, r1, r22545; V7A-T-NEXT: rsb.w r2, r3, #642546; V7A-T-NEXT: lsr.w r1, r1, r122547; V7A-T-NEXT: mov.w r3, #-12548; V7A-T-NEXT: it pl2549; V7A-T-NEXT: movpl r1, #02550; V7A-T-NEXT: uxtb.w r12, r22551; V7A-T-NEXT: uxtab r2, lr, r22552; V7A-T-NEXT: lsr.w r0, r3, r122553; V7A-T-NEXT: cmp r2, #02554; V7A-T-NEXT: it pl2555; V7A-T-NEXT: movpl r0, #02556; V7A-T-NEXT: and.w r1, r1, r02557; V7A-T-NEXT: it pl2558; V7A-T-NEXT: lsrpl r3, r22559; V7A-T-NEXT: and.w r0, r3, r42560; V7A-T-NEXT: pop {r4, pc}2561;2562; V6M-LABEL: bextr64_c1_indexzext:2563; V6M: @ %bb.0:2564; V6M-NEXT: .save {r4, r5, r6, lr}2565; V6M-NEXT: push {r4, r5, r6, lr}2566; V6M-NEXT: mov r5, r32567; V6M-NEXT: uxtb r2, r22568; V6M-NEXT: bl __aeabi_llsr2569; V6M-NEXT: mov r6, r02570; V6M-NEXT: mov r4, r12571; V6M-NEXT: movs r0, #642572; V6M-NEXT: subs r0, r0, r52573; V6M-NEXT: uxtb r2, r02574; V6M-NEXT: movs r0, #02575; V6M-NEXT: mvns r0, r02576; V6M-NEXT: mov r1, r02577; V6M-NEXT: bl __aeabi_llsr2578; V6M-NEXT: ands r0, r62579; V6M-NEXT: ands r1, r42580; V6M-NEXT: pop {r4, r5, r6, pc}2581 %skip = zext i8 %numskipbits to i642582 %shifted = lshr i64 %val, %skip2583 %numhighbits = sub i8 64, %numlowbits2584 %sh_prom = zext i8 %numhighbits to i642585 %mask = lshr i64 -1, %sh_prom2586 %masked = and i64 %mask, %shifted2587 ret i64 %masked2588}2589 2590define i64 @bextr64_c2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {2591; V7M-LABEL: bextr64_c2_load:2592; V7M: @ %bb.0:2593; V7M-NEXT: ldrd r0, r3, [r0]2594; V7M-NEXT: rsb.w r1, r2, #322595; V7M-NEXT: ldr.w r12, [sp]2596; V7M-NEXT: lsl.w r1, r3, r12597; V7M-NEXT: lsrs r0, r22598; V7M-NEXT: orrs r0, r12599; V7M-NEXT: subs.w r1, r2, #322600; V7M-NEXT: it pl2601; V7M-NEXT: lsrpl.w r0, r3, r12602; V7M-NEXT: lsr.w r1, r3, r22603; V7M-NEXT: rsb.w r3, r12, #642604; V7M-NEXT: mov.w r2, #-12605; V7M-NEXT: it pl2606; V7M-NEXT: movpl r1, #02607; V7M-NEXT: rsbs.w r12, r12, #322608; V7M-NEXT: lsr.w r3, r2, r32609; V7M-NEXT: it pl2610; V7M-NEXT: movpl r3, #02611; V7M-NEXT: it pl2612; V7M-NEXT: lsrpl.w r2, r2, r122613; V7M-NEXT: ands r1, r32614; V7M-NEXT: ands r0, r22615; V7M-NEXT: bx lr2616;2617; V7A-LABEL: bextr64_c2_load:2618; V7A: @ %bb.0:2619; V7A-NEXT: .save {r4, r6, r8, lr}2620; V7A-NEXT: push {r4, r6, r8, lr}2621; V7A-NEXT: ldr r12, [sp, #16]2622; V7A-NEXT: ldr r3, [r0, #4]2623; V7A-NEXT: rsb r6, r12, #642624; V7A-NEXT: ldr r8, [r0]2625; V7A-NEXT: mvn r0, #02626; V7A-NEXT: rsbs r1, r12, #322627; V7A-NEXT: lsr r6, r0, r62628; V7A-NEXT: lsr r4, r3, r22629; V7A-NEXT: lsrpl r0, r0, r12630; V7A-NEXT: movwpl r6, #02631; V7A-NEXT: subs r12, r2, #322632; V7A-NEXT: movwpl r4, #02633; V7A-NEXT: and r1, r6, r42634; V7A-NEXT: lsr r6, r8, r22635; V7A-NEXT: rsb r2, r2, #322636; V7A-NEXT: orr r2, r6, r3, lsl r22637; V7A-NEXT: lsrpl r2, r3, r122638; V7A-NEXT: and r0, r0, r22639; V7A-NEXT: pop {r4, r6, r8, pc}2640;2641; V7A-T-LABEL: bextr64_c2_load:2642; V7A-T: @ %bb.0:2643; V7A-T-NEXT: ldrd r0, r3, [r0]2644; V7A-T-NEXT: rsb.w r1, r2, #322645; V7A-T-NEXT: ldr.w r12, [sp]2646; V7A-T-NEXT: lsl.w r1, r3, r12647; V7A-T-NEXT: lsrs r0, r22648; V7A-T-NEXT: orrs r0, r12649; V7A-T-NEXT: subs.w r1, r2, #322650; V7A-T-NEXT: it pl2651; V7A-T-NEXT: lsrpl.w r0, r3, r12652; V7A-T-NEXT: lsr.w r1, r3, r22653; V7A-T-NEXT: rsb.w r2, r12, #642654; V7A-T-NEXT: mov.w r3, #-12655; V7A-T-NEXT: it pl2656; V7A-T-NEXT: movpl r1, #02657; V7A-T-NEXT: rsbs.w r12, r12, #322658; V7A-T-NEXT: lsr.w r2, r3, r22659; V7A-T-NEXT: it pl2660; V7A-T-NEXT: movpl r2, #02661; V7A-T-NEXT: it pl2662; V7A-T-NEXT: lsrpl.w r3, r3, r122663; V7A-T-NEXT: ands r1, r22664; V7A-T-NEXT: ands r0, r32665; V7A-T-NEXT: bx lr2666;2667; V6M-LABEL: bextr64_c2_load:2668; V6M: @ %bb.0:2669; V6M-NEXT: .save {r4, r5, r7, lr}2670; V6M-NEXT: push {r4, r5, r7, lr}2671; V6M-NEXT: ldr r3, [r0]2672; V6M-NEXT: ldr r1, [r0, #4]2673; V6M-NEXT: mov r0, r32674; V6M-NEXT: bl __aeabi_llsr2675; V6M-NEXT: mov r5, r02676; V6M-NEXT: mov r4, r12677; V6M-NEXT: ldr r0, [sp, #16]2678; V6M-NEXT: movs r1, #642679; V6M-NEXT: subs r2, r1, r02680; V6M-NEXT: movs r0, #02681; V6M-NEXT: mvns r0, r02682; V6M-NEXT: mov r1, r02683; V6M-NEXT: bl __aeabi_llsr2684; V6M-NEXT: ands r0, r52685; V6M-NEXT: ands r1, r42686; V6M-NEXT: pop {r4, r5, r7, pc}2687 %val = load i64, ptr %w2688 %shifted = lshr i64 %val, %numskipbits2689 %numhighbits = sub i64 64, %numlowbits2690 %mask = lshr i64 -1, %numhighbits2691 %masked = and i64 %mask, %shifted2692 ret i64 %masked2693}2694 2695define i64 @bextr64_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {2696; V7M-LABEL: bextr64_c3_load_indexzext:2697; V7M: @ %bb.0:2698; V7M-NEXT: .save {r7, lr}2699; V7M-NEXT: push {r7, lr}2700; V7M-NEXT: ldrd r0, r3, [r0]2701; V7M-NEXT: uxtb r1, r12702; V7M-NEXT: lsr.w r12, r0, r12703; V7M-NEXT: rsb.w r0, r1, #322704; V7M-NEXT: lsl.w r0, r3, r02705; V7M-NEXT: orr.w r12, r12, r02706; V7M-NEXT: subs.w r0, r1, #322707; V7M-NEXT: it pl2708; V7M-NEXT: lsrpl.w r12, r3, r02709; V7M-NEXT: rsb.w r0, r2, #642710; V7M-NEXT: lsr.w r1, r3, r12711; V7M-NEXT: mov.w r3, #-12712; V7M-NEXT: it pl2713; V7M-NEXT: movpl r1, #02714; V7M-NEXT: uxtb r0, r02715; V7M-NEXT: subs.w lr, r0, #322716; V7M-NEXT: lsr.w r2, r3, r02717; V7M-NEXT: it pl2718; V7M-NEXT: lsrpl.w r3, r3, lr2719; V7M-NEXT: it pl2720; V7M-NEXT: movpl r2, #02721; V7M-NEXT: and.w r0, r3, r122722; V7M-NEXT: ands r1, r22723; V7M-NEXT: pop {r7, pc}2724;2725; V7A-LABEL: bextr64_c3_load_indexzext:2726; V7A: @ %bb.0:2727; V7A-NEXT: .save {r4, lr}2728; V7A-NEXT: push {r4, lr}2729; V7A-NEXT: ldr r4, [r0]2730; V7A-NEXT: ldr r3, [r0, #4]2731; V7A-NEXT: uxtb r0, r12732; V7A-NEXT: lsr r12, r4, r02733; V7A-NEXT: rsb r4, r0, #322734; V7A-NEXT: lsr r0, r3, r02735; V7A-NEXT: orr lr, r12, r3, lsl r42736; V7A-NEXT: mvn r12, #312737; V7A-NEXT: uxtab r1, r12, r12738; V7A-NEXT: cmp r1, #02739; V7A-NEXT: lsrpl lr, r3, r12740; V7A-NEXT: rsb r1, r2, #642741; V7A-NEXT: mvn r3, #02742; V7A-NEXT: movwpl r0, #02743; V7A-NEXT: uxtb r2, r12744; V7A-NEXT: uxtab r4, r12, r12745; V7A-NEXT: lsr r2, r3, r22746; V7A-NEXT: cmp r4, #02747; V7A-NEXT: movwpl r2, #02748; V7A-NEXT: and r1, r2, r02749; V7A-NEXT: lsrpl r3, r3, r42750; V7A-NEXT: and r0, r3, lr2751; V7A-NEXT: pop {r4, pc}2752;2753; V7A-T-LABEL: bextr64_c3_load_indexzext:2754; V7A-T: @ %bb.0:2755; V7A-T-NEXT: .save {r4, r5, r7, lr}2756; V7A-T-NEXT: push {r4, r5, r7, lr}2757; V7A-T-NEXT: ldrd r12, lr, [r0]2758; V7A-T-NEXT: uxtb r0, r12759; V7A-T-NEXT: rsb.w r3, r0, #322760; V7A-T-NEXT: lsl.w r4, lr, r32761; V7A-T-NEXT: lsr.w r3, r12, r02762; V7A-T-NEXT: orr.w r5, r3, r42763; V7A-T-NEXT: mvn r12, #312764; V7A-T-NEXT: uxtab r1, r12, r12765; V7A-T-NEXT: lsr.w r0, lr, r02766; V7A-T-NEXT: cmp r1, #02767; V7A-T-NEXT: it pl2768; V7A-T-NEXT: lsrpl.w r5, lr, r12769; V7A-T-NEXT: rsb.w r1, r2, #642770; V7A-T-NEXT: mov.w r4, #-12771; V7A-T-NEXT: it pl2772; V7A-T-NEXT: movpl r0, #02773; V7A-T-NEXT: uxtb r2, r12774; V7A-T-NEXT: uxtab r3, r12, r12775; V7A-T-NEXT: lsr.w r2, r4, r22776; V7A-T-NEXT: cmp r3, #02777; V7A-T-NEXT: it pl2778; V7A-T-NEXT: movpl r2, #02779; V7A-T-NEXT: and.w r1, r2, r02780; V7A-T-NEXT: it pl2781; V7A-T-NEXT: lsrpl r4, r32782; V7A-T-NEXT: and.w r0, r4, r52783; V7A-T-NEXT: pop {r4, r5, r7, pc}2784;2785; V6M-LABEL: bextr64_c3_load_indexzext:2786; V6M: @ %bb.0:2787; V6M-NEXT: .save {r4, r5, r6, lr}2788; V6M-NEXT: push {r4, r5, r6, lr}2789; V6M-NEXT: mov r5, r22790; V6M-NEXT: ldr r4, [r0]2791; V6M-NEXT: ldr r3, [r0, #4]2792; V6M-NEXT: uxtb r2, r12793; V6M-NEXT: mov r0, r42794; V6M-NEXT: mov r1, r32795; V6M-NEXT: bl __aeabi_llsr2796; V6M-NEXT: mov r6, r02797; V6M-NEXT: mov r4, r12798; V6M-NEXT: movs r0, #642799; V6M-NEXT: subs r0, r0, r52800; V6M-NEXT: uxtb r2, r02801; V6M-NEXT: movs r0, #02802; V6M-NEXT: mvns r0, r02803; V6M-NEXT: mov r1, r02804; V6M-NEXT: bl __aeabi_llsr2805; V6M-NEXT: ands r0, r62806; V6M-NEXT: ands r1, r42807; V6M-NEXT: pop {r4, r5, r6, pc}2808 %val = load i64, ptr %w2809 %skip = zext i8 %numskipbits to i642810 %shifted = lshr i64 %val, %skip2811 %numhighbits = sub i8 64, %numlowbits2812 %sh_prom = zext i8 %numhighbits to i642813 %mask = lshr i64 -1, %sh_prom2814 %masked = and i64 %mask, %shifted2815 ret i64 %masked2816}2817 2818define i64 @bextr64_c4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {2819; V7M-LABEL: bextr64_c4_commutative:2820; V7M: @ %bb.0:2821; V7M-NEXT: rsb.w r3, r2, #322822; V7M-NEXT: lsrs r0, r22823; V7M-NEXT: ldr.w r12, [sp]2824; V7M-NEXT: lsl.w r3, r1, r32825; V7M-NEXT: orrs r0, r32826; V7M-NEXT: subs.w r3, r2, #322827; V7M-NEXT: it pl2828; V7M-NEXT: lsrpl.w r0, r1, r32829; V7M-NEXT: rsb.w r3, r12, #642830; V7M-NEXT: lsr.w r1, r1, r22831; V7M-NEXT: mov.w r2, #-12832; V7M-NEXT: it pl2833; V7M-NEXT: movpl r1, #02834; V7M-NEXT: lsr.w r3, r2, r32835; V7M-NEXT: rsbs.w r12, r12, #322836; V7M-NEXT: it pl2837; V7M-NEXT: movpl r3, #02838; V7M-NEXT: it pl2839; V7M-NEXT: lsrpl.w r2, r2, r122840; V7M-NEXT: ands r1, r32841; V7M-NEXT: ands r0, r22842; V7M-NEXT: bx lr2843;2844; V7A-LABEL: bextr64_c4_commutative:2845; V7A: @ %bb.0:2846; V7A-NEXT: .save {r4, r5, r11, lr}2847; V7A-NEXT: push {r4, r5, r11, lr}2848; V7A-NEXT: ldr r12, [sp, #16]2849; V7A-NEXT: mvn r3, #02850; V7A-NEXT: lsr r5, r1, r22851; V7A-NEXT: lsr r0, r0, r22852; V7A-NEXT: rsb r4, r12, #642853; V7A-NEXT: rsbs lr, r12, #322854; V7A-NEXT: lsr r4, r3, r42855; V7A-NEXT: lsrpl r3, r3, lr2856; V7A-NEXT: movwpl r4, #02857; V7A-NEXT: subs lr, r2, #322858; V7A-NEXT: rsb r2, r2, #322859; V7A-NEXT: movwpl r5, #02860; V7A-NEXT: and r12, r5, r42861; V7A-NEXT: orr r0, r0, r1, lsl r22862; V7A-NEXT: lsrpl r0, r1, lr2863; V7A-NEXT: mov r1, r122864; V7A-NEXT: and r0, r0, r32865; V7A-NEXT: pop {r4, r5, r11, pc}2866;2867; V7A-T-LABEL: bextr64_c4_commutative:2868; V7A-T: @ %bb.0:2869; V7A-T-NEXT: .save {r7, lr}2870; V7A-T-NEXT: push {r7, lr}2871; V7A-T-NEXT: rsb.w r3, r2, #322872; V7A-T-NEXT: lsrs r0, r22873; V7A-T-NEXT: ldr.w r12, [sp, #8]2874; V7A-T-NEXT: mov.w lr, #-12875; V7A-T-NEXT: lsl.w r3, r1, r32876; V7A-T-NEXT: orrs r0, r32877; V7A-T-NEXT: subs.w r3, r2, #322878; V7A-T-NEXT: it pl2879; V7A-T-NEXT: lsrpl.w r0, r1, r32880; V7A-T-NEXT: lsr.w r1, r1, r22881; V7A-T-NEXT: mov.w r3, #-12882; V7A-T-NEXT: it pl2883; V7A-T-NEXT: movpl r1, #02884; V7A-T-NEXT: rsbs.w r2, r12, #322885; V7A-T-NEXT: it pl2886; V7A-T-NEXT: lsrpl r3, r22887; V7A-T-NEXT: rsb.w r2, r12, #642888; V7A-T-NEXT: and.w r0, r0, r32889; V7A-T-NEXT: lsr.w r2, lr, r22890; V7A-T-NEXT: it pl2891; V7A-T-NEXT: movpl r2, #02892; V7A-T-NEXT: ands r1, r22893; V7A-T-NEXT: pop {r7, pc}2894;2895; V6M-LABEL: bextr64_c4_commutative:2896; V6M: @ %bb.0:2897; V6M-NEXT: .save {r4, r5, r7, lr}2898; V6M-NEXT: push {r4, r5, r7, lr}2899; V6M-NEXT: bl __aeabi_llsr2900; V6M-NEXT: mov r5, r02901; V6M-NEXT: mov r4, r12902; V6M-NEXT: ldr r0, [sp, #16]2903; V6M-NEXT: movs r1, #642904; V6M-NEXT: subs r2, r1, r02905; V6M-NEXT: movs r0, #02906; V6M-NEXT: mvns r0, r02907; V6M-NEXT: mov r1, r02908; V6M-NEXT: bl __aeabi_llsr2909; V6M-NEXT: ands r0, r52910; V6M-NEXT: ands r1, r42911; V6M-NEXT: pop {r4, r5, r7, pc}2912 %shifted = lshr i64 %val, %numskipbits2913 %numhighbits = sub i64 64, %numlowbits2914 %mask = lshr i64 -1, %numhighbits2915 %masked = and i64 %shifted, %mask ; swapped order2916 ret i64 %masked2917}2918 2919; 64-bit, but with 32-bit output2920 2921; Everything done in 64-bit, truncation happens last.2922define i32 @bextr64_32_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {2923; V7M-LABEL: bextr64_32_c0:2924; V7M: @ %bb.0:2925; V7M-NEXT: rsb.w r3, r2, #322926; V7M-NEXT: lsrs r0, r22927; V7M-NEXT: subs r2, #322928; V7M-NEXT: lsl.w r3, r1, r32929; V7M-NEXT: orr.w r0, r0, r32930; V7M-NEXT: it pl2931; V7M-NEXT: lsrpl.w r0, r1, r22932; V7M-NEXT: ldr r1, [sp]2933; V7M-NEXT: mov.w r2, #-12934; V7M-NEXT: rsbs.w r1, r1, #322935; V7M-NEXT: it pl2936; V7M-NEXT: lsrpl r2, r12937; V7M-NEXT: ands r0, r22938; V7M-NEXT: bx lr2939;2940; V7A-LABEL: bextr64_32_c0:2941; V7A: @ %bb.0:2942; V7A-NEXT: ldr r3, [sp]2943; V7A-NEXT: rsbs r12, r3, #322944; V7A-NEXT: mvn r3, #02945; V7A-NEXT: lsrpl r3, r3, r122946; V7A-NEXT: lsr r12, r0, r22947; V7A-NEXT: rsb r0, r2, #322948; V7A-NEXT: subs r2, r2, #322949; V7A-NEXT: orr r0, r12, r1, lsl r02950; V7A-NEXT: lsrpl r0, r1, r22951; V7A-NEXT: and r0, r3, r02952; V7A-NEXT: bx lr2953;2954; V7A-T-LABEL: bextr64_32_c0:2955; V7A-T: @ %bb.0:2956; V7A-T-NEXT: rsb.w r3, r2, #322957; V7A-T-NEXT: lsrs r0, r22958; V7A-T-NEXT: ldr.w r12, [sp]2959; V7A-T-NEXT: subs r2, #322960; V7A-T-NEXT: lsl.w r3, r1, r32961; V7A-T-NEXT: orr.w r0, r0, r32962; V7A-T-NEXT: it pl2963; V7A-T-NEXT: lsrpl.w r0, r1, r22964; V7A-T-NEXT: mov.w r2, #-12965; V7A-T-NEXT: rsbs.w r1, r12, #322966; V7A-T-NEXT: it pl2967; V7A-T-NEXT: lsrpl r2, r12968; V7A-T-NEXT: ands r0, r22969; V7A-T-NEXT: bx lr2970;2971; V6M-LABEL: bextr64_32_c0:2972; V6M: @ %bb.0:2973; V6M-NEXT: .save {r4, lr}2974; V6M-NEXT: push {r4, lr}2975; V6M-NEXT: bl __aeabi_llsr2976; V6M-NEXT: mov r4, r02977; V6M-NEXT: ldr r0, [sp, #8]2978; V6M-NEXT: movs r1, #642979; V6M-NEXT: subs r2, r1, r02980; V6M-NEXT: movs r0, #02981; V6M-NEXT: mvns r0, r02982; V6M-NEXT: mov r1, r02983; V6M-NEXT: bl __aeabi_llsr2984; V6M-NEXT: ands r0, r42985; V6M-NEXT: pop {r4, pc}2986 %shifted = lshr i64 %val, %numskipbits2987 %numhighbits = sub i64 64, %numlowbits2988 %mask = lshr i64 -1, %numhighbits2989 %masked = and i64 %mask, %shifted2990 %res = trunc i64 %masked to i322991 ret i32 %res2992}2993 2994; Shifting happens in 64-bit, then truncation. Masking is 32-bit.2995define i32 @bextr64_32_c1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {2996; V7M-LABEL: bextr64_32_c1:2997; V7M: @ %bb.0:2998; V7M-NEXT: rsb.w r3, r2, #322999; V7M-NEXT: lsrs r0, r23000; V7M-NEXT: subs r2, #323001; V7M-NEXT: lsl.w r3, r1, r33002; V7M-NEXT: orr.w r0, r0, r33003; V7M-NEXT: it pl3004; V7M-NEXT: lsrpl.w r0, r1, r23005; V7M-NEXT: ldr r1, [sp]3006; V7M-NEXT: rsb.w r1, r1, #323007; V7M-NEXT: lsls r0, r13008; V7M-NEXT: lsrs r0, r13009; V7M-NEXT: bx lr3010;3011; V7A-LABEL: bextr64_32_c1:3012; V7A: @ %bb.0:3013; V7A-NEXT: rsb r3, r2, #323014; V7A-NEXT: lsr r0, r0, r23015; V7A-NEXT: ldr r12, [sp]3016; V7A-NEXT: subs r2, r2, #323017; V7A-NEXT: orr r0, r0, r1, lsl r33018; V7A-NEXT: lsrpl r0, r1, r23019; V7A-NEXT: rsb r1, r12, #323020; V7A-NEXT: lsl r0, r0, r13021; V7A-NEXT: lsr r0, r0, r13022; V7A-NEXT: bx lr3023;3024; V7A-T-LABEL: bextr64_32_c1:3025; V7A-T: @ %bb.0:3026; V7A-T-NEXT: rsb.w r3, r2, #323027; V7A-T-NEXT: lsrs r0, r23028; V7A-T-NEXT: ldr.w r12, [sp]3029; V7A-T-NEXT: subs r2, #323030; V7A-T-NEXT: lsl.w r3, r1, r33031; V7A-T-NEXT: orr.w r0, r0, r33032; V7A-T-NEXT: it pl3033; V7A-T-NEXT: lsrpl.w r0, r1, r23034; V7A-T-NEXT: rsb.w r1, r12, #323035; V7A-T-NEXT: lsls r0, r13036; V7A-T-NEXT: lsrs r0, r13037; V7A-T-NEXT: bx lr3038;3039; V6M-LABEL: bextr64_32_c1:3040; V6M: @ %bb.0:3041; V6M-NEXT: .save {r7, lr}3042; V6M-NEXT: push {r7, lr}3043; V6M-NEXT: bl __aeabi_llsr3044; V6M-NEXT: ldr r1, [sp, #8]3045; V6M-NEXT: movs r2, #323046; V6M-NEXT: subs r1, r2, r13047; V6M-NEXT: lsls r0, r13048; V6M-NEXT: lsrs r0, r13049; V6M-NEXT: pop {r7, pc}3050 %shifted = lshr i64 %val, %numskipbits3051 %truncshifted = trunc i64 %shifted to i323052 %numhighbits = sub i32 32, %numlowbits3053 %mask = lshr i32 -1, %numhighbits3054 %masked = and i32 %mask, %truncshifted3055 ret i32 %masked3056}3057 3058; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.3059; Masking is 64-bit. Then truncation.3060define i32 @bextr64_32_c2(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {3061; V7M-LABEL: bextr64_32_c2:3062; V7M: @ %bb.0:3063; V7M-NEXT: rsb.w r3, r2, #323064; V7M-NEXT: lsrs r0, r23065; V7M-NEXT: subs r2, #323066; V7M-NEXT: lsl.w r3, r1, r33067; V7M-NEXT: orr.w r0, r0, r33068; V7M-NEXT: it pl3069; V7M-NEXT: lsrpl.w r0, r1, r23070; V7M-NEXT: ldr r1, [sp]3071; V7M-NEXT: rsb.w r1, r1, #323072; V7M-NEXT: lsls r0, r13073; V7M-NEXT: lsrs r0, r13074; V7M-NEXT: bx lr3075;3076; V7A-LABEL: bextr64_32_c2:3077; V7A: @ %bb.0:3078; V7A-NEXT: rsb r3, r2, #323079; V7A-NEXT: lsr r0, r0, r23080; V7A-NEXT: ldr r12, [sp]3081; V7A-NEXT: subs r2, r2, #323082; V7A-NEXT: orr r0, r0, r1, lsl r33083; V7A-NEXT: lsrpl r0, r1, r23084; V7A-NEXT: rsb r1, r12, #323085; V7A-NEXT: lsl r0, r0, r13086; V7A-NEXT: lsr r0, r0, r13087; V7A-NEXT: bx lr3088;3089; V7A-T-LABEL: bextr64_32_c2:3090; V7A-T: @ %bb.0:3091; V7A-T-NEXT: rsb.w r3, r2, #323092; V7A-T-NEXT: lsrs r0, r23093; V7A-T-NEXT: ldr.w r12, [sp]3094; V7A-T-NEXT: subs r2, #323095; V7A-T-NEXT: lsl.w r3, r1, r33096; V7A-T-NEXT: orr.w r0, r0, r33097; V7A-T-NEXT: it pl3098; V7A-T-NEXT: lsrpl.w r0, r1, r23099; V7A-T-NEXT: rsb.w r1, r12, #323100; V7A-T-NEXT: lsls r0, r13101; V7A-T-NEXT: lsrs r0, r13102; V7A-T-NEXT: bx lr3103;3104; V6M-LABEL: bextr64_32_c2:3105; V6M: @ %bb.0:3106; V6M-NEXT: .save {r7, lr}3107; V6M-NEXT: push {r7, lr}3108; V6M-NEXT: bl __aeabi_llsr3109; V6M-NEXT: ldr r1, [sp, #8]3110; V6M-NEXT: movs r2, #323111; V6M-NEXT: subs r1, r2, r13112; V6M-NEXT: lsls r0, r13113; V6M-NEXT: lsrs r0, r13114; V6M-NEXT: pop {r7, pc}3115 %shifted = lshr i64 %val, %numskipbits3116 %numhighbits = sub i32 32, %numlowbits3117 %mask = lshr i32 -1, %numhighbits3118 %zextmask = zext i32 %mask to i643119 %masked = and i64 %zextmask, %shifted3120 %truncmasked = trunc i64 %masked to i323121 ret i32 %truncmasked3122}3123 3124; ---------------------------------------------------------------------------- ;3125; Pattern d. 32-bit.3126; ---------------------------------------------------------------------------- ;3127 3128define i32 @bextr32_d0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {3129; V7M-LABEL: bextr32_d0:3130; V7M: @ %bb.0:3131; V7M-NEXT: lsrs r0, r13132; V7M-NEXT: rsb.w r1, r2, #323133; V7M-NEXT: lsls r0, r13134; V7M-NEXT: lsrs r0, r13135; V7M-NEXT: bx lr3136;3137; V7A-LABEL: bextr32_d0:3138; V7A: @ %bb.0:3139; V7A-NEXT: lsr r0, r0, r13140; V7A-NEXT: rsb r1, r2, #323141; V7A-NEXT: lsl r0, r0, r13142; V7A-NEXT: lsr r0, r0, r13143; V7A-NEXT: bx lr3144;3145; V7A-T-LABEL: bextr32_d0:3146; V7A-T: @ %bb.0:3147; V7A-T-NEXT: lsrs r0, r13148; V7A-T-NEXT: rsb.w r1, r2, #323149; V7A-T-NEXT: lsls r0, r13150; V7A-T-NEXT: lsrs r0, r13151; V7A-T-NEXT: bx lr3152;3153; V6M-LABEL: bextr32_d0:3154; V6M: @ %bb.0:3155; V6M-NEXT: movs r3, #323156; V6M-NEXT: subs r2, r3, r23157; V6M-NEXT: lsrs r0, r13158; V6M-NEXT: lsls r0, r23159; V6M-NEXT: lsrs r0, r23160; V6M-NEXT: bx lr3161 %shifted = lshr i32 %val, %numskipbits3162 %numhighbits = sub i32 32, %numlowbits3163 %highbitscleared = shl i32 %shifted, %numhighbits3164 %masked = lshr i32 %highbitscleared, %numhighbits3165 ret i32 %masked3166}3167 3168define i32 @bextr32_d1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind {3169; V7M-LABEL: bextr32_d1_indexzext:3170; V7M: @ %bb.0:3171; V7M-NEXT: uxtb r1, r13172; V7M-NEXT: lsrs r0, r13173; V7M-NEXT: rsb.w r1, r2, #323174; V7M-NEXT: uxtb r1, r13175; V7M-NEXT: lsls r0, r13176; V7M-NEXT: lsrs r0, r13177; V7M-NEXT: bx lr3178;3179; V7A-LABEL: bextr32_d1_indexzext:3180; V7A: @ %bb.0:3181; V7A-NEXT: uxtb r1, r13182; V7A-NEXT: lsr r0, r0, r13183; V7A-NEXT: rsb r1, r2, #323184; V7A-NEXT: uxtb r1, r13185; V7A-NEXT: lsl r0, r0, r13186; V7A-NEXT: lsr r0, r0, r13187; V7A-NEXT: bx lr3188;3189; V7A-T-LABEL: bextr32_d1_indexzext:3190; V7A-T: @ %bb.0:3191; V7A-T-NEXT: uxtb r1, r13192; V7A-T-NEXT: lsrs r0, r13193; V7A-T-NEXT: rsb.w r1, r2, #323194; V7A-T-NEXT: uxtb r1, r13195; V7A-T-NEXT: lsls r0, r13196; V7A-T-NEXT: lsrs r0, r13197; V7A-T-NEXT: bx lr3198;3199; V6M-LABEL: bextr32_d1_indexzext:3200; V6M: @ %bb.0:3201; V6M-NEXT: uxtb r1, r13202; V6M-NEXT: lsrs r0, r13203; V6M-NEXT: movs r1, #323204; V6M-NEXT: subs r1, r1, r23205; V6M-NEXT: uxtb r1, r13206; V6M-NEXT: lsls r0, r13207; V6M-NEXT: lsrs r0, r13208; V6M-NEXT: bx lr3209 %skip = zext i8 %numskipbits to i323210 %shifted = lshr i32 %val, %skip3211 %numhighbits = sub i8 32, %numlowbits3212 %sh_prom = zext i8 %numhighbits to i323213 %highbitscleared = shl i32 %shifted, %sh_prom3214 %masked = lshr i32 %highbitscleared, %sh_prom3215 ret i32 %masked3216}3217 3218define i32 @bextr32_d2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {3219; V7M-LABEL: bextr32_d2_load:3220; V7M: @ %bb.0:3221; V7M-NEXT: ldr r0, [r0]3222; V7M-NEXT: lsrs r0, r13223; V7M-NEXT: rsb.w r1, r2, #323224; V7M-NEXT: lsls r0, r13225; V7M-NEXT: lsrs r0, r13226; V7M-NEXT: bx lr3227;3228; V7A-LABEL: bextr32_d2_load:3229; V7A: @ %bb.0:3230; V7A-NEXT: ldr r0, [r0]3231; V7A-NEXT: lsr r0, r0, r13232; V7A-NEXT: rsb r1, r2, #323233; V7A-NEXT: lsl r0, r0, r13234; V7A-NEXT: lsr r0, r0, r13235; V7A-NEXT: bx lr3236;3237; V7A-T-LABEL: bextr32_d2_load:3238; V7A-T: @ %bb.0:3239; V7A-T-NEXT: ldr r0, [r0]3240; V7A-T-NEXT: lsrs r0, r13241; V7A-T-NEXT: rsb.w r1, r2, #323242; V7A-T-NEXT: lsls r0, r13243; V7A-T-NEXT: lsrs r0, r13244; V7A-T-NEXT: bx lr3245;3246; V6M-LABEL: bextr32_d2_load:3247; V6M: @ %bb.0:3248; V6M-NEXT: movs r3, #323249; V6M-NEXT: subs r2, r3, r23250; V6M-NEXT: ldr r0, [r0]3251; V6M-NEXT: lsrs r0, r13252; V6M-NEXT: lsls r0, r23253; V6M-NEXT: lsrs r0, r23254; V6M-NEXT: bx lr3255 %val = load i32, ptr %w3256 %shifted = lshr i32 %val, %numskipbits3257 %numhighbits = sub i32 32, %numlowbits3258 %highbitscleared = shl i32 %shifted, %numhighbits3259 %masked = lshr i32 %highbitscleared, %numhighbits3260 ret i32 %masked3261}3262 3263define i32 @bextr32_d3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {3264; V7M-LABEL: bextr32_d3_load_indexzext:3265; V7M: @ %bb.0:3266; V7M-NEXT: ldr r0, [r0]3267; V7M-NEXT: uxtb r1, r13268; V7M-NEXT: lsrs r0, r13269; V7M-NEXT: rsb.w r1, r2, #323270; V7M-NEXT: uxtb r1, r13271; V7M-NEXT: lsls r0, r13272; V7M-NEXT: lsrs r0, r13273; V7M-NEXT: bx lr3274;3275; V7A-LABEL: bextr32_d3_load_indexzext:3276; V7A: @ %bb.0:3277; V7A-NEXT: ldr r0, [r0]3278; V7A-NEXT: uxtb r1, r13279; V7A-NEXT: lsr r0, r0, r13280; V7A-NEXT: rsb r1, r2, #323281; V7A-NEXT: uxtb r1, r13282; V7A-NEXT: lsl r0, r0, r13283; V7A-NEXT: lsr r0, r0, r13284; V7A-NEXT: bx lr3285;3286; V7A-T-LABEL: bextr32_d3_load_indexzext:3287; V7A-T: @ %bb.0:3288; V7A-T-NEXT: ldr r0, [r0]3289; V7A-T-NEXT: uxtb r1, r13290; V7A-T-NEXT: lsrs r0, r13291; V7A-T-NEXT: rsb.w r1, r2, #323292; V7A-T-NEXT: uxtb r1, r13293; V7A-T-NEXT: lsls r0, r13294; V7A-T-NEXT: lsrs r0, r13295; V7A-T-NEXT: bx lr3296;3297; V6M-LABEL: bextr32_d3_load_indexzext:3298; V6M: @ %bb.0:3299; V6M-NEXT: uxtb r1, r13300; V6M-NEXT: ldr r0, [r0]3301; V6M-NEXT: lsrs r0, r13302; V6M-NEXT: movs r1, #323303; V6M-NEXT: subs r1, r1, r23304; V6M-NEXT: uxtb r1, r13305; V6M-NEXT: lsls r0, r13306; V6M-NEXT: lsrs r0, r13307; V6M-NEXT: bx lr3308 %val = load i32, ptr %w3309 %skip = zext i8 %numskipbits to i323310 %shifted = lshr i32 %val, %skip3311 %numhighbits = sub i8 32, %numlowbits3312 %sh_prom = zext i8 %numhighbits to i323313 %highbitscleared = shl i32 %shifted, %sh_prom3314 %masked = lshr i32 %highbitscleared, %sh_prom3315 ret i32 %masked3316}3317 3318; 64-bit.3319 3320define i64 @bextr64_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {3321; V7M-LABEL: bextr64_d0:3322; V7M: @ %bb.0:3323; V7M-NEXT: .save {r4, lr}3324; V7M-NEXT: push {r4, lr}3325; V7M-NEXT: rsb.w r3, r2, #323326; V7M-NEXT: ldr.w r12, [sp, #8]3327; V7M-NEXT: lsrs r0, r23328; V7M-NEXT: lsl.w r3, r1, r33329; V7M-NEXT: orrs r0, r33330; V7M-NEXT: subs.w r3, r2, #323331; V7M-NEXT: it pl3332; V7M-NEXT: lsrpl.w r0, r1, r33333; V7M-NEXT: lsr.w r1, r1, r23334; V7M-NEXT: rsb.w r3, r12, #643335; V7M-NEXT: it pl3336; V7M-NEXT: movpl r1, #03337; V7M-NEXT: rsb.w lr, r12, #323338; V7M-NEXT: rsb.w r12, r3, #323339; V7M-NEXT: lsls r1, r33340; V7M-NEXT: cmp.w lr, #03341; V7M-NEXT: lsr.w r4, r0, r123342; V7M-NEXT: orr.w r1, r1, r43343; V7M-NEXT: it pl3344; V7M-NEXT: lslpl.w r1, r0, lr3345; V7M-NEXT: lsl.w r0, r0, r33346; V7M-NEXT: it pl3347; V7M-NEXT: movpl r0, #03348; V7M-NEXT: lsl.w r2, r1, r123349; V7M-NEXT: lsr.w r0, r0, r33350; V7M-NEXT: orr.w r0, r0, r23351; V7M-NEXT: it pl3352; V7M-NEXT: lsrpl.w r0, r1, lr3353; V7M-NEXT: lsr.w r1, r1, r33354; V7M-NEXT: it pl3355; V7M-NEXT: movpl r1, #03356; V7M-NEXT: pop {r4, pc}3357;3358; V7A-LABEL: bextr64_d0:3359; V7A: @ %bb.0:3360; V7A-NEXT: .save {r11, lr}3361; V7A-NEXT: push {r11, lr}3362; V7A-NEXT: lsr r3, r1, r23363; V7A-NEXT: subs lr, r2, #323364; V7A-NEXT: lsr r0, r0, r23365; V7A-NEXT: rsb r2, r2, #323366; V7A-NEXT: ldr r12, [sp, #8]3367; V7A-NEXT: movwpl r3, #03368; V7A-NEXT: orr r0, r0, r1, lsl r23369; V7A-NEXT: lsrpl r0, r1, lr3370; V7A-NEXT: rsb r1, r12, #643371; V7A-NEXT: rsb lr, r1, #323372; V7A-NEXT: lsr r2, r0, lr3373; V7A-NEXT: orr r2, r2, r3, lsl r13374; V7A-NEXT: rsbs r3, r12, #323375; V7A-NEXT: lslpl r2, r0, r33376; V7A-NEXT: lsl r0, r0, r13377; V7A-NEXT: movwpl r0, #03378; V7A-NEXT: lsr r0, r0, r13379; V7A-NEXT: lsr r1, r2, r13380; V7A-NEXT: orr r0, r0, r2, lsl lr3381; V7A-NEXT: movwpl r1, #03382; V7A-NEXT: lsrpl r0, r2, r33383; V7A-NEXT: pop {r11, pc}3384;3385; V7A-T-LABEL: bextr64_d0:3386; V7A-T: @ %bb.0:3387; V7A-T-NEXT: .save {r4, lr}3388; V7A-T-NEXT: push {r4, lr}3389; V7A-T-NEXT: rsb.w r3, r2, #323390; V7A-T-NEXT: ldr.w r12, [sp, #8]3391; V7A-T-NEXT: lsrs r0, r23392; V7A-T-NEXT: lsl.w r3, r1, r33393; V7A-T-NEXT: orrs r0, r33394; V7A-T-NEXT: subs.w r3, r2, #323395; V7A-T-NEXT: it pl3396; V7A-T-NEXT: lsrpl.w r0, r1, r33397; V7A-T-NEXT: lsr.w r1, r1, r23398; V7A-T-NEXT: rsb.w r3, r12, #643399; V7A-T-NEXT: it pl3400; V7A-T-NEXT: movpl r1, #03401; V7A-T-NEXT: rsb.w lr, r3, #323402; V7A-T-NEXT: lsls r1, r33403; V7A-T-NEXT: rsbs.w r2, r12, #323404; V7A-T-NEXT: lsr.w r4, r0, lr3405; V7A-T-NEXT: orr.w r1, r1, r43406; V7A-T-NEXT: it pl3407; V7A-T-NEXT: lslpl.w r1, r0, r23408; V7A-T-NEXT: lsl.w r0, r0, r33409; V7A-T-NEXT: it pl3410; V7A-T-NEXT: movpl r0, #03411; V7A-T-NEXT: lsl.w r4, r1, lr3412; V7A-T-NEXT: lsr.w r0, r0, r33413; V7A-T-NEXT: orr.w r0, r0, r43414; V7A-T-NEXT: it pl3415; V7A-T-NEXT: lsrpl.w r0, r1, r23416; V7A-T-NEXT: lsr.w r1, r1, r33417; V7A-T-NEXT: it pl3418; V7A-T-NEXT: movpl r1, #03419; V7A-T-NEXT: pop {r4, pc}3420;3421; V6M-LABEL: bextr64_d0:3422; V6M: @ %bb.0:3423; V6M-NEXT: .save {r4, lr}3424; V6M-NEXT: push {r4, lr}3425; V6M-NEXT: bl __aeabi_llsr3426; V6M-NEXT: ldr r2, [sp, #8]3427; V6M-NEXT: movs r3, #643428; V6M-NEXT: subs r4, r3, r23429; V6M-NEXT: mov r2, r43430; V6M-NEXT: bl __aeabi_llsl3431; V6M-NEXT: mov r2, r43432; V6M-NEXT: bl __aeabi_llsr3433; V6M-NEXT: pop {r4, pc}3434 %shifted = lshr i64 %val, %numskipbits3435 %numhighbits = sub i64 64, %numlowbits3436 %highbitscleared = shl i64 %shifted, %numhighbits3437 %masked = lshr i64 %highbitscleared, %numhighbits3438 ret i64 %masked3439}3440 3441define i64 @bextr64_d1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind {3442; V7M-LABEL: bextr64_d1_indexzext:3443; V7M: @ %bb.0:3444; V7M-NEXT: .save {r4, lr}3445; V7M-NEXT: push {r4, lr}3446; V7M-NEXT: uxtb.w lr, r23447; V7M-NEXT: subs.w r2, lr, #323448; V7M-NEXT: lsr.w r12, r0, lr3449; V7M-NEXT: rsb.w r0, lr, #323450; V7M-NEXT: lsl.w r0, r1, r03451; V7M-NEXT: orr.w r0, r0, r123452; V7M-NEXT: it pl3453; V7M-NEXT: lsrpl.w r0, r1, r23454; V7M-NEXT: rsb.w r2, r3, #643455; V7M-NEXT: lsr.w r1, r1, lr3456; V7M-NEXT: uxtb r2, r23457; V7M-NEXT: it pl3458; V7M-NEXT: movpl r1, #03459; V7M-NEXT: rsb.w r3, r2, #323460; V7M-NEXT: lsls r1, r23461; V7M-NEXT: sub.w r12, r2, #323462; V7M-NEXT: lsr.w r4, r0, r33463; V7M-NEXT: orrs r1, r43464; V7M-NEXT: cmp.w r12, #03465; V7M-NEXT: it pl3466; V7M-NEXT: lslpl.w r1, r0, r123467; V7M-NEXT: lsl.w r0, r0, r23468; V7M-NEXT: lsl.w r3, r1, r33469; V7M-NEXT: it pl3470; V7M-NEXT: movpl r0, #03471; V7M-NEXT: lsr.w r0, r0, r23472; V7M-NEXT: orr.w r0, r0, r33473; V7M-NEXT: it pl3474; V7M-NEXT: lsrpl.w r0, r1, r123475; V7M-NEXT: lsr.w r1, r1, r23476; V7M-NEXT: it pl3477; V7M-NEXT: movpl r1, #03478; V7M-NEXT: pop {r4, pc}3479;3480; V7A-LABEL: bextr64_d1_indexzext:3481; V7A: @ %bb.0:3482; V7A-NEXT: .save {r4, r5, r11, lr}3483; V7A-NEXT: push {r4, r5, r11, lr}3484; V7A-NEXT: uxtb r12, r23485; V7A-NEXT: lsr lr, r0, r123486; V7A-NEXT: rsb r0, r12, #323487; V7A-NEXT: orr r0, lr, r1, lsl r03488; V7A-NEXT: mvn lr, #313489; V7A-NEXT: uxtab r2, lr, r23490; V7A-NEXT: cmp r2, #03491; V7A-NEXT: lsrpl r0, r1, r23492; V7A-NEXT: rsb r2, r3, #643493; V7A-NEXT: lsr r1, r1, r123494; V7A-NEXT: uxtb r3, r23495; V7A-NEXT: rsb r4, r3, #323496; V7A-NEXT: movwpl r1, #03497; V7A-NEXT: uxtab r2, lr, r23498; V7A-NEXT: lsr r5, r0, r43499; V7A-NEXT: orr r1, r5, r1, lsl r33500; V7A-NEXT: cmp r2, #03501; V7A-NEXT: lslpl r1, r0, r23502; V7A-NEXT: lsl r0, r0, r33503; V7A-NEXT: movwpl r0, #03504; V7A-NEXT: lsr r0, r0, r33505; V7A-NEXT: orr r0, r0, r1, lsl r43506; V7A-NEXT: lsrpl r0, r1, r23507; V7A-NEXT: lsr r1, r1, r33508; V7A-NEXT: movwpl r1, #03509; V7A-NEXT: pop {r4, r5, r11, pc}3510;3511; V7A-T-LABEL: bextr64_d1_indexzext:3512; V7A-T: @ %bb.0:3513; V7A-T-NEXT: .save {r4, r5, r6, r7, lr}3514; V7A-T-NEXT: push {r4, r5, r6, r7, lr}3515; V7A-T-NEXT: uxtb.w r12, r23516; V7A-T-NEXT: rsb.w r6, r12, #323517; V7A-T-NEXT: rsb.w r3, r3, #643518; V7A-T-NEXT: lsr.w r0, r0, r123519; V7A-T-NEXT: mvn r7, #313520; V7A-T-NEXT: uxtab r2, r7, r23521; V7A-T-NEXT: lsl.w r6, r1, r63522; V7A-T-NEXT: lsr.w lr, r1, r123523; V7A-T-NEXT: orrs r0, r63524; V7A-T-NEXT: cmp r2, #03525; V7A-T-NEXT: it pl3526; V7A-T-NEXT: movpl.w lr, #03527; V7A-T-NEXT: uxtb r5, r33528; V7A-T-NEXT: it pl3529; V7A-T-NEXT: lsrpl.w r0, r1, r23530; V7A-T-NEXT: rsb.w r1, r5, #323531; V7A-T-NEXT: uxtab r3, r7, r33532; V7A-T-NEXT: lsl.w r4, lr, r53533; V7A-T-NEXT: lsr.w r2, r0, r13534; V7A-T-NEXT: cmp r3, #03535; V7A-T-NEXT: orr.w r2, r2, r43536; V7A-T-NEXT: it pl3537; V7A-T-NEXT: lslpl.w r2, r0, r33538; V7A-T-NEXT: lsl.w r0, r0, r53539; V7A-T-NEXT: it pl3540; V7A-T-NEXT: movpl r0, #03541; V7A-T-NEXT: lsl.w r1, r2, r13542; V7A-T-NEXT: lsr.w r0, r0, r53543; V7A-T-NEXT: orr.w r0, r0, r13544; V7A-T-NEXT: lsr.w r1, r2, r53545; V7A-T-NEXT: it pl3546; V7A-T-NEXT: lsrpl.w r0, r2, r33547; V7A-T-NEXT: it pl3548; V7A-T-NEXT: movpl r1, #03549; V7A-T-NEXT: pop {r4, r5, r6, r7, pc}3550;3551; V6M-LABEL: bextr64_d1_indexzext:3552; V6M: @ %bb.0:3553; V6M-NEXT: .save {r4, lr}3554; V6M-NEXT: push {r4, lr}3555; V6M-NEXT: mov r4, r33556; V6M-NEXT: uxtb r2, r23557; V6M-NEXT: bl __aeabi_llsr3558; V6M-NEXT: movs r2, #643559; V6M-NEXT: subs r2, r2, r43560; V6M-NEXT: uxtb r4, r23561; V6M-NEXT: mov r2, r43562; V6M-NEXT: bl __aeabi_llsl3563; V6M-NEXT: mov r2, r43564; V6M-NEXT: bl __aeabi_llsr3565; V6M-NEXT: pop {r4, pc}3566 %skip = zext i8 %numskipbits to i643567 %shifted = lshr i64 %val, %skip3568 %numhighbits = sub i8 64, %numlowbits3569 %sh_prom = zext i8 %numhighbits to i643570 %highbitscleared = shl i64 %shifted, %sh_prom3571 %masked = lshr i64 %highbitscleared, %sh_prom3572 ret i64 %masked3573}3574 3575define i64 @bextr64_d2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {3576; V7M-LABEL: bextr64_d2_load:3577; V7M: @ %bb.0:3578; V7M-NEXT: .save {r4, lr}3579; V7M-NEXT: push {r4, lr}3580; V7M-NEXT: ldrd r0, r3, [r0]3581; V7M-NEXT: rsb.w r1, r2, #323582; V7M-NEXT: ldr.w r12, [sp, #8]3583; V7M-NEXT: lsl.w r1, r3, r13584; V7M-NEXT: lsrs r0, r23585; V7M-NEXT: rsb.w lr, r12, #323586; V7M-NEXT: orrs r0, r13587; V7M-NEXT: subs.w r1, r2, #323588; V7M-NEXT: it pl3589; V7M-NEXT: lsrpl.w r0, r3, r13590; V7M-NEXT: rsb.w r1, r12, #643591; V7M-NEXT: lsr.w r2, r3, r23592; V7M-NEXT: rsb.w r12, r1, #323593; V7M-NEXT: it pl3594; V7M-NEXT: movpl r2, #03595; V7M-NEXT: cmp.w lr, #03596; V7M-NEXT: lsl.w r2, r2, r13597; V7M-NEXT: lsr.w r4, r0, r123598; V7M-NEXT: orr.w r2, r2, r43599; V7M-NEXT: it pl3600; V7M-NEXT: lslpl.w r2, r0, lr3601; V7M-NEXT: lsl.w r0, r0, r13602; V7M-NEXT: it pl3603; V7M-NEXT: movpl r0, #03604; V7M-NEXT: lsl.w r3, r2, r123605; V7M-NEXT: lsr.w r0, r0, r13606; V7M-NEXT: lsr.w r1, r2, r13607; V7M-NEXT: orr.w r0, r0, r33608; V7M-NEXT: it pl3609; V7M-NEXT: lsrpl.w r0, r2, lr3610; V7M-NEXT: it pl3611; V7M-NEXT: movpl r1, #03612; V7M-NEXT: pop {r4, pc}3613;3614; V7A-LABEL: bextr64_d2_load:3615; V7A: @ %bb.0:3616; V7A-NEXT: .save {r11, lr}3617; V7A-NEXT: push {r11, lr}3618; V7A-NEXT: ldrd r0, r1, [r0]3619; V7A-NEXT: subs lr, r2, #323620; V7A-NEXT: lsr r3, r1, r23621; V7A-NEXT: ldr r12, [sp, #8]3622; V7A-NEXT: movwpl r3, #03623; V7A-NEXT: lsr r0, r0, r23624; V7A-NEXT: rsb r2, r2, #323625; V7A-NEXT: orr r0, r0, r1, lsl r23626; V7A-NEXT: lsrpl r0, r1, lr3627; V7A-NEXT: rsb r1, r12, #643628; V7A-NEXT: rsb lr, r1, #323629; V7A-NEXT: lsr r2, r0, lr3630; V7A-NEXT: orr r2, r2, r3, lsl r13631; V7A-NEXT: rsbs r3, r12, #323632; V7A-NEXT: lslpl r2, r0, r33633; V7A-NEXT: lsl r0, r0, r13634; V7A-NEXT: movwpl r0, #03635; V7A-NEXT: lsr r0, r0, r13636; V7A-NEXT: lsr r1, r2, r13637; V7A-NEXT: orr r0, r0, r2, lsl lr3638; V7A-NEXT: movwpl r1, #03639; V7A-NEXT: lsrpl r0, r2, r33640; V7A-NEXT: pop {r11, pc}3641;3642; V7A-T-LABEL: bextr64_d2_load:3643; V7A-T: @ %bb.0:3644; V7A-T-NEXT: .save {r4, lr}3645; V7A-T-NEXT: push {r4, lr}3646; V7A-T-NEXT: ldrd r0, r3, [r0]3647; V7A-T-NEXT: rsb.w r1, r2, #323648; V7A-T-NEXT: ldr.w r12, [sp, #8]3649; V7A-T-NEXT: lsl.w r1, r3, r13650; V7A-T-NEXT: lsrs r0, r23651; V7A-T-NEXT: orrs r0, r13652; V7A-T-NEXT: subs.w r1, r2, #323653; V7A-T-NEXT: it pl3654; V7A-T-NEXT: lsrpl.w r0, r3, r13655; V7A-T-NEXT: lsr.w r2, r3, r23656; V7A-T-NEXT: rsb.w r1, r12, #643657; V7A-T-NEXT: it pl3658; V7A-T-NEXT: movpl r2, #03659; V7A-T-NEXT: rsb.w lr, r1, #323660; V7A-T-NEXT: rsbs.w r3, r12, #323661; V7A-T-NEXT: lsl.w r2, r2, r13662; V7A-T-NEXT: lsr.w r4, r0, lr3663; V7A-T-NEXT: orr.w r2, r2, r43664; V7A-T-NEXT: it pl3665; V7A-T-NEXT: lslpl.w r2, r0, r33666; V7A-T-NEXT: lsl.w r0, r0, r13667; V7A-T-NEXT: it pl3668; V7A-T-NEXT: movpl r0, #03669; V7A-T-NEXT: lsl.w r4, r2, lr3670; V7A-T-NEXT: lsr.w r0, r0, r13671; V7A-T-NEXT: lsr.w r1, r2, r13672; V7A-T-NEXT: orr.w r0, r0, r43673; V7A-T-NEXT: it pl3674; V7A-T-NEXT: lsrpl.w r0, r2, r33675; V7A-T-NEXT: it pl3676; V7A-T-NEXT: movpl r1, #03677; V7A-T-NEXT: pop {r4, pc}3678;3679; V6M-LABEL: bextr64_d2_load:3680; V6M: @ %bb.0:3681; V6M-NEXT: .save {r4, lr}3682; V6M-NEXT: push {r4, lr}3683; V6M-NEXT: ldr r3, [r0]3684; V6M-NEXT: ldr r1, [r0, #4]3685; V6M-NEXT: mov r0, r33686; V6M-NEXT: bl __aeabi_llsr3687; V6M-NEXT: ldr r2, [sp, #8]3688; V6M-NEXT: movs r3, #643689; V6M-NEXT: subs r4, r3, r23690; V6M-NEXT: mov r2, r43691; V6M-NEXT: bl __aeabi_llsl3692; V6M-NEXT: mov r2, r43693; V6M-NEXT: bl __aeabi_llsr3694; V6M-NEXT: pop {r4, pc}3695 %val = load i64, ptr %w3696 %shifted = lshr i64 %val, %numskipbits3697 %numhighbits = sub i64 64, %numlowbits3698 %highbitscleared = shl i64 %shifted, %numhighbits3699 %masked = lshr i64 %highbitscleared, %numhighbits3700 ret i64 %masked3701}3702 3703define i64 @bextr64_d3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {3704; V7M-LABEL: bextr64_d3_load_indexzext:3705; V7M: @ %bb.0:3706; V7M-NEXT: .save {r4, lr}3707; V7M-NEXT: push {r4, lr}3708; V7M-NEXT: ldrd r0, lr, [r0]3709; V7M-NEXT: uxtb r1, r13710; V7M-NEXT: rsb.w r2, r2, #643711; V7M-NEXT: subs.w r3, r1, #323712; V7M-NEXT: lsr.w r12, r0, r13713; V7M-NEXT: rsb.w r0, r1, #323714; V7M-NEXT: lsr.w r1, lr, r13715; V7M-NEXT: uxtb r2, r23716; V7M-NEXT: lsl.w r0, lr, r03717; V7M-NEXT: orr.w r0, r0, r123718; V7M-NEXT: sub.w r12, r2, #323719; V7M-NEXT: it pl3720; V7M-NEXT: lsrpl.w r0, lr, r33721; V7M-NEXT: it pl3722; V7M-NEXT: movpl r1, #03723; V7M-NEXT: rsb.w r3, r2, #323724; V7M-NEXT: lsls r1, r23725; V7M-NEXT: cmp.w r12, #03726; V7M-NEXT: lsr.w r4, r0, r33727; V7M-NEXT: orr.w r1, r1, r43728; V7M-NEXT: it pl3729; V7M-NEXT: lslpl.w r1, r0, r123730; V7M-NEXT: lsl.w r0, r0, r23731; V7M-NEXT: it pl3732; V7M-NEXT: movpl r0, #03733; V7M-NEXT: lsl.w r3, r1, r33734; V7M-NEXT: lsr.w r0, r0, r23735; V7M-NEXT: orr.w r0, r0, r33736; V7M-NEXT: it pl3737; V7M-NEXT: lsrpl.w r0, r1, r123738; V7M-NEXT: lsr.w r1, r1, r23739; V7M-NEXT: it pl3740; V7M-NEXT: movpl r1, #03741; V7M-NEXT: pop {r4, pc}3742;3743; V7A-LABEL: bextr64_d3_load_indexzext:3744; V7A: @ %bb.0:3745; V7A-NEXT: .save {r4, r5, r11, lr}3746; V7A-NEXT: push {r4, r5, r11, lr}3747; V7A-NEXT: ldr r4, [r0]3748; V7A-NEXT: ldr r3, [r0, #4]3749; V7A-NEXT: uxtb r0, r13750; V7A-NEXT: lsr r12, r4, r03751; V7A-NEXT: rsb r4, r0, #323752; V7A-NEXT: lsr r0, r3, r03753; V7A-NEXT: orr r4, r12, r3, lsl r43754; V7A-NEXT: mvn r12, #313755; V7A-NEXT: uxtab r1, r12, r13756; V7A-NEXT: cmp r1, #03757; V7A-NEXT: lsrpl r4, r3, r13758; V7A-NEXT: rsb r1, r2, #643759; V7A-NEXT: movwpl r0, #03760; V7A-NEXT: uxtb r2, r13761; V7A-NEXT: rsb lr, r2, #323762; V7A-NEXT: uxtab r1, r12, r13763; V7A-NEXT: lsr r5, r4, lr3764; V7A-NEXT: orr r3, r5, r0, lsl r23765; V7A-NEXT: cmp r1, #03766; V7A-NEXT: lsl r0, r4, r23767; V7A-NEXT: movwpl r0, #03768; V7A-NEXT: lslpl r3, r4, r13769; V7A-NEXT: lsr r0, r0, r23770; V7A-NEXT: orr r0, r0, r3, lsl lr3771; V7A-NEXT: lsrpl r0, r3, r13772; V7A-NEXT: lsr r1, r3, r23773; V7A-NEXT: movwpl r1, #03774; V7A-NEXT: pop {r4, r5, r11, pc}3775;3776; V7A-T-LABEL: bextr64_d3_load_indexzext:3777; V7A-T: @ %bb.0:3778; V7A-T-NEXT: .save {r4, r5, r6, lr}3779; V7A-T-NEXT: push {r4, r5, r6, lr}3780; V7A-T-NEXT: ldrd r12, lr, [r0]3781; V7A-T-NEXT: uxtb r0, r13782; V7A-T-NEXT: rsb.w r6, r0, #323783; V7A-T-NEXT: lsr.w r3, lr, r03784; V7A-T-NEXT: rsb.w r2, r2, #643785; V7A-T-NEXT: mvn r4, #313786; V7A-T-NEXT: lsr.w r0, r12, r03787; V7A-T-NEXT: uxtab r1, r4, r13788; V7A-T-NEXT: lsl.w r6, lr, r63789; V7A-T-NEXT: orrs r0, r63790; V7A-T-NEXT: cmp r1, #03791; V7A-T-NEXT: it pl3792; V7A-T-NEXT: movpl r3, #03793; V7A-T-NEXT: uxtb r5, r23794; V7A-T-NEXT: it pl3795; V7A-T-NEXT: lsrpl.w r0, lr, r13796; V7A-T-NEXT: rsb.w r1, r5, #323797; V7A-T-NEXT: lsls r3, r53798; V7A-T-NEXT: uxtab r2, r4, r23799; V7A-T-NEXT: lsr.w r6, r0, r13800; V7A-T-NEXT: orrs r3, r63801; V7A-T-NEXT: cmp r2, #03802; V7A-T-NEXT: it pl3803; V7A-T-NEXT: lslpl.w r3, r0, r23804; V7A-T-NEXT: lsl.w r0, r0, r53805; V7A-T-NEXT: lsl.w r1, r3, r13806; V7A-T-NEXT: it pl3807; V7A-T-NEXT: movpl r0, #03808; V7A-T-NEXT: lsr.w r0, r0, r53809; V7A-T-NEXT: orr.w r0, r0, r13810; V7A-T-NEXT: lsr.w r1, r3, r53811; V7A-T-NEXT: it pl3812; V7A-T-NEXT: lsrpl.w r0, r3, r23813; V7A-T-NEXT: it pl3814; V7A-T-NEXT: movpl r1, #03815; V7A-T-NEXT: pop {r4, r5, r6, pc}3816;3817; V6M-LABEL: bextr64_d3_load_indexzext:3818; V6M: @ %bb.0:3819; V6M-NEXT: .save {r4, r5, r7, lr}3820; V6M-NEXT: push {r4, r5, r7, lr}3821; V6M-NEXT: mov r4, r23822; V6M-NEXT: ldr r5, [r0]3823; V6M-NEXT: ldr r3, [r0, #4]3824; V6M-NEXT: uxtb r2, r13825; V6M-NEXT: mov r0, r53826; V6M-NEXT: mov r1, r33827; V6M-NEXT: bl __aeabi_llsr3828; V6M-NEXT: movs r2, #643829; V6M-NEXT: subs r2, r2, r43830; V6M-NEXT: uxtb r4, r23831; V6M-NEXT: mov r2, r43832; V6M-NEXT: bl __aeabi_llsl3833; V6M-NEXT: mov r2, r43834; V6M-NEXT: bl __aeabi_llsr3835; V6M-NEXT: pop {r4, r5, r7, pc}3836 %val = load i64, ptr %w3837 %skip = zext i8 %numskipbits to i643838 %shifted = lshr i64 %val, %skip3839 %numhighbits = sub i8 64, %numlowbits3840 %sh_prom = zext i8 %numhighbits to i643841 %highbitscleared = shl i64 %shifted, %sh_prom3842 %masked = lshr i64 %highbitscleared, %sh_prom3843 ret i64 %masked3844}3845 3846; 64-bit, but with 32-bit output3847 3848; Everything done in 64-bit, truncation happens last.3849define i32 @bextr64_32_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {3850; V7M-LABEL: bextr64_32_d0:3851; V7M: @ %bb.0:3852; V7M-NEXT: .save {r4, lr}3853; V7M-NEXT: push {r4, lr}3854; V7M-NEXT: rsb.w r3, r2, #323855; V7M-NEXT: ldr.w r12, [sp, #8]3856; V7M-NEXT: lsrs r0, r23857; V7M-NEXT: lsl.w r3, r1, r33858; V7M-NEXT: orrs r0, r33859; V7M-NEXT: subs.w r3, r2, #323860; V7M-NEXT: it pl3861; V7M-NEXT: lsrpl.w r0, r1, r33862; V7M-NEXT: lsr.w r1, r1, r23863; V7M-NEXT: rsb.w r3, r12, #643864; V7M-NEXT: it pl3865; V7M-NEXT: movpl r1, #03866; V7M-NEXT: rsb.w lr, r12, #323867; V7M-NEXT: rsb.w r12, r3, #323868; V7M-NEXT: lsls r1, r33869; V7M-NEXT: cmp.w lr, #03870; V7M-NEXT: lsr.w r4, r0, r123871; V7M-NEXT: orr.w r1, r1, r43872; V7M-NEXT: it pl3873; V7M-NEXT: lslpl.w r1, r0, lr3874; V7M-NEXT: lsl.w r0, r0, r33875; V7M-NEXT: it pl3876; V7M-NEXT: movpl r0, #03877; V7M-NEXT: lsl.w r2, r1, r123878; V7M-NEXT: lsr.w r0, r0, r33879; V7M-NEXT: orr.w r0, r0, r23880; V7M-NEXT: it pl3881; V7M-NEXT: lsrpl.w r0, r1, lr3882; V7M-NEXT: pop {r4, pc}3883;3884; V7A-LABEL: bextr64_32_d0:3885; V7A: @ %bb.0:3886; V7A-NEXT: .save {r11, lr}3887; V7A-NEXT: push {r11, lr}3888; V7A-NEXT: lsr r3, r1, r23889; V7A-NEXT: subs lr, r2, #323890; V7A-NEXT: lsr r0, r0, r23891; V7A-NEXT: rsb r2, r2, #323892; V7A-NEXT: ldr r12, [sp, #8]3893; V7A-NEXT: movwpl r3, #03894; V7A-NEXT: orr r0, r0, r1, lsl r23895; V7A-NEXT: lsrpl r0, r1, lr3896; V7A-NEXT: rsb r1, r12, #643897; V7A-NEXT: rsb lr, r1, #323898; V7A-NEXT: lsr r2, r0, lr3899; V7A-NEXT: orr r2, r2, r3, lsl r13900; V7A-NEXT: rsbs r3, r12, #323901; V7A-NEXT: lslpl r2, r0, r33902; V7A-NEXT: lsl r0, r0, r13903; V7A-NEXT: movwpl r0, #03904; V7A-NEXT: lsr r0, r0, r13905; V7A-NEXT: orr r0, r0, r2, lsl lr3906; V7A-NEXT: lsrpl r0, r2, r33907; V7A-NEXT: pop {r11, pc}3908;3909; V7A-T-LABEL: bextr64_32_d0:3910; V7A-T: @ %bb.0:3911; V7A-T-NEXT: .save {r4, lr}3912; V7A-T-NEXT: push {r4, lr}3913; V7A-T-NEXT: rsb.w r3, r2, #323914; V7A-T-NEXT: ldr.w r12, [sp, #8]3915; V7A-T-NEXT: lsrs r0, r23916; V7A-T-NEXT: lsl.w r3, r1, r33917; V7A-T-NEXT: orrs r0, r33918; V7A-T-NEXT: subs.w r3, r2, #323919; V7A-T-NEXT: it pl3920; V7A-T-NEXT: lsrpl.w r0, r1, r33921; V7A-T-NEXT: lsr.w r1, r1, r23922; V7A-T-NEXT: rsb.w r3, r12, #643923; V7A-T-NEXT: it pl3924; V7A-T-NEXT: movpl r1, #03925; V7A-T-NEXT: rsb.w lr, r3, #323926; V7A-T-NEXT: lsls r1, r33927; V7A-T-NEXT: rsbs.w r2, r12, #323928; V7A-T-NEXT: lsr.w r4, r0, lr3929; V7A-T-NEXT: orr.w r1, r1, r43930; V7A-T-NEXT: it pl3931; V7A-T-NEXT: lslpl.w r1, r0, r23932; V7A-T-NEXT: lsl.w r0, r0, r33933; V7A-T-NEXT: it pl3934; V7A-T-NEXT: movpl r0, #03935; V7A-T-NEXT: lsl.w r4, r1, lr3936; V7A-T-NEXT: lsr.w r0, r0, r33937; V7A-T-NEXT: orr.w r0, r0, r43938; V7A-T-NEXT: it pl3939; V7A-T-NEXT: lsrpl.w r0, r1, r23940; V7A-T-NEXT: pop {r4, pc}3941;3942; V6M-LABEL: bextr64_32_d0:3943; V6M: @ %bb.0:3944; V6M-NEXT: .save {r4, lr}3945; V6M-NEXT: push {r4, lr}3946; V6M-NEXT: bl __aeabi_llsr3947; V6M-NEXT: ldr r2, [sp, #8]3948; V6M-NEXT: movs r3, #643949; V6M-NEXT: subs r4, r3, r23950; V6M-NEXT: mov r2, r43951; V6M-NEXT: bl __aeabi_llsl3952; V6M-NEXT: mov r2, r43953; V6M-NEXT: bl __aeabi_llsr3954; V6M-NEXT: pop {r4, pc}3955 %shifted = lshr i64 %val, %numskipbits3956 %numhighbits = sub i64 64, %numlowbits3957 %highbitscleared = shl i64 %shifted, %numhighbits3958 %masked = lshr i64 %highbitscleared, %numhighbits3959 %res = trunc i64 %masked to i323960 ret i32 %res3961}3962 3963; Shifting happens in 64-bit, then truncation. Masking is 32-bit.3964define i32 @bextr64_32_d1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {3965; V7M-LABEL: bextr64_32_d1:3966; V7M: @ %bb.0:3967; V7M-NEXT: rsb.w r3, r2, #323968; V7M-NEXT: lsrs r0, r23969; V7M-NEXT: subs r2, #323970; V7M-NEXT: lsl.w r3, r1, r33971; V7M-NEXT: orr.w r0, r0, r33972; V7M-NEXT: it pl3973; V7M-NEXT: lsrpl.w r0, r1, r23974; V7M-NEXT: ldr r1, [sp]3975; V7M-NEXT: rsb.w r1, r1, #323976; V7M-NEXT: lsls r0, r13977; V7M-NEXT: lsrs r0, r13978; V7M-NEXT: bx lr3979;3980; V7A-LABEL: bextr64_32_d1:3981; V7A: @ %bb.0:3982; V7A-NEXT: rsb r3, r2, #323983; V7A-NEXT: lsr r0, r0, r23984; V7A-NEXT: ldr r12, [sp]3985; V7A-NEXT: subs r2, r2, #323986; V7A-NEXT: orr r0, r0, r1, lsl r33987; V7A-NEXT: lsrpl r0, r1, r23988; V7A-NEXT: rsb r1, r12, #323989; V7A-NEXT: lsl r0, r0, r13990; V7A-NEXT: lsr r0, r0, r13991; V7A-NEXT: bx lr3992;3993; V7A-T-LABEL: bextr64_32_d1:3994; V7A-T: @ %bb.0:3995; V7A-T-NEXT: rsb.w r3, r2, #323996; V7A-T-NEXT: lsrs r0, r23997; V7A-T-NEXT: ldr.w r12, [sp]3998; V7A-T-NEXT: subs r2, #323999; V7A-T-NEXT: lsl.w r3, r1, r34000; V7A-T-NEXT: orr.w r0, r0, r34001; V7A-T-NEXT: it pl4002; V7A-T-NEXT: lsrpl.w r0, r1, r24003; V7A-T-NEXT: rsb.w r1, r12, #324004; V7A-T-NEXT: lsls r0, r14005; V7A-T-NEXT: lsrs r0, r14006; V7A-T-NEXT: bx lr4007;4008; V6M-LABEL: bextr64_32_d1:4009; V6M: @ %bb.0:4010; V6M-NEXT: .save {r7, lr}4011; V6M-NEXT: push {r7, lr}4012; V6M-NEXT: bl __aeabi_llsr4013; V6M-NEXT: ldr r1, [sp, #8]4014; V6M-NEXT: movs r2, #324015; V6M-NEXT: subs r1, r2, r14016; V6M-NEXT: lsls r0, r14017; V6M-NEXT: lsrs r0, r14018; V6M-NEXT: pop {r7, pc}4019 %shifted = lshr i64 %val, %numskipbits4020 %truncshifted = trunc i64 %shifted to i324021 %numhighbits = sub i32 32, %numlowbits4022 %highbitscleared = shl i32 %truncshifted, %numhighbits4023 %masked = lshr i32 %highbitscleared, %numhighbits4024 ret i32 %masked4025}4026 4027; ---------------------------------------------------------------------------- ;4028; Constant4029; ---------------------------------------------------------------------------- ;4030 4031; https://bugs.llvm.org/show_bug.cgi?id=389384032define void @pr38938(ptr %a0, ptr %a1) nounwind {4033; V7M-LABEL: pr38938:4034; V7M: @ %bb.0:4035; V7M-NEXT: ldr r1, [r1]4036; V7M-NEXT: ubfx r1, r1, #21, #104037; V7M-NEXT: ldr.w r2, [r0, r1, lsl #2]4038; V7M-NEXT: adds r2, #14039; V7M-NEXT: str.w r2, [r0, r1, lsl #2]4040; V7M-NEXT: bx lr4041;4042; V7A-LABEL: pr38938:4043; V7A: @ %bb.0:4044; V7A-NEXT: ldr r1, [r1]4045; V7A-NEXT: ubfx r1, r1, #21, #104046; V7A-NEXT: ldr r2, [r0, r1, lsl #2]4047; V7A-NEXT: add r2, r2, #14048; V7A-NEXT: str r2, [r0, r1, lsl #2]4049; V7A-NEXT: bx lr4050;4051; V7A-T-LABEL: pr38938:4052; V7A-T: @ %bb.0:4053; V7A-T-NEXT: ldr r1, [r1]4054; V7A-T-NEXT: ubfx r1, r1, #21, #104055; V7A-T-NEXT: ldr.w r2, [r0, r1, lsl #2]4056; V7A-T-NEXT: adds r2, #14057; V7A-T-NEXT: str.w r2, [r0, r1, lsl #2]4058; V7A-T-NEXT: bx lr4059;4060; V6M-LABEL: pr38938:4061; V6M: @ %bb.0:4062; V6M-NEXT: ldr r1, [r1]4063; V6M-NEXT: lsrs r1, r1, #194064; V6M-NEXT: ldr r2, .LCPI51_04065; V6M-NEXT: ands r2, r14066; V6M-NEXT: ldr r1, [r0, r2]4067; V6M-NEXT: adds r1, r1, #14068; V6M-NEXT: str r1, [r0, r2]4069; V6M-NEXT: bx lr4070; V6M-NEXT: .p2align 24071; V6M-NEXT: @ %bb.1:4072; V6M-NEXT: .LCPI51_0:4073; V6M-NEXT: .long 4092 @ 0xffc4074 %tmp = load i64, ptr %a1, align 84075 %tmp1 = lshr i64 %tmp, 214076 %tmp2 = and i64 %tmp1, 10234077 %tmp3 = getelementptr inbounds i32, ptr %a0, i64 %tmp24078 %tmp4 = load i32, ptr %tmp3, align 44079 %tmp5 = add nsw i32 %tmp4, 14080 store i32 %tmp5, ptr %tmp3, align 44081 ret void4082}4083 4084; The most canonical variant4085define i32 @c0_i32(i32 %arg) nounwind {4086; V7M-LABEL: c0_i32:4087; V7M: @ %bb.0:4088; V7M-NEXT: ubfx r0, r0, #19, #104089; V7M-NEXT: bx lr4090;4091; V7A-LABEL: c0_i32:4092; V7A: @ %bb.0:4093; V7A-NEXT: ubfx r0, r0, #19, #104094; V7A-NEXT: bx lr4095;4096; V7A-T-LABEL: c0_i32:4097; V7A-T: @ %bb.0:4098; V7A-T-NEXT: ubfx r0, r0, #19, #104099; V7A-T-NEXT: bx lr4100;4101; V6M-LABEL: c0_i32:4102; V6M: @ %bb.0:4103; V6M-NEXT: lsls r0, r0, #34104; V6M-NEXT: lsrs r0, r0, #224105; V6M-NEXT: bx lr4106 %tmp0 = lshr i32 %arg, 194107 %tmp1 = and i32 %tmp0, 10234108 ret i32 %tmp14109}4110 4111; Should be still fine, but the mask is shifted4112define i32 @c1_i32(i32 %arg) nounwind {4113; V7M-LABEL: c1_i32:4114; V7M: @ %bb.0:4115; V7M-NEXT: movw r1, #40924116; V7M-NEXT: and.w r0, r1, r0, lsr #194117; V7M-NEXT: bx lr4118;4119; V7A-LABEL: c1_i32:4120; V7A: @ %bb.0:4121; V7A-NEXT: movw r1, #40924122; V7A-NEXT: and r0, r1, r0, lsr #194123; V7A-NEXT: bx lr4124;4125; V7A-T-LABEL: c1_i32:4126; V7A-T: @ %bb.0:4127; V7A-T-NEXT: movw r1, #40924128; V7A-T-NEXT: and.w r0, r1, r0, lsr #194129; V7A-T-NEXT: bx lr4130;4131; V6M-LABEL: c1_i32:4132; V6M: @ %bb.0:4133; V6M-NEXT: lsrs r1, r0, #194134; V6M-NEXT: ldr r0, .LCPI53_04135; V6M-NEXT: ands r0, r14136; V6M-NEXT: bx lr4137; V6M-NEXT: .p2align 24138; V6M-NEXT: @ %bb.1:4139; V6M-NEXT: .LCPI53_0:4140; V6M-NEXT: .long 4092 @ 0xffc4141 %tmp0 = lshr i32 %arg, 194142 %tmp1 = and i32 %tmp0, 40924143 ret i32 %tmp14144}4145 4146; Should be still fine, but the result is shifted left afterwards4147define i32 @c2_i32(i32 %arg) nounwind {4148; V7M-LABEL: c2_i32:4149; V7M: @ %bb.0:4150; V7M-NEXT: movw r1, #40924151; V7M-NEXT: and.w r0, r1, r0, lsr #174152; V7M-NEXT: bx lr4153;4154; V7A-LABEL: c2_i32:4155; V7A: @ %bb.0:4156; V7A-NEXT: movw r1, #40924157; V7A-NEXT: and r0, r1, r0, lsr #174158; V7A-NEXT: bx lr4159;4160; V7A-T-LABEL: c2_i32:4161; V7A-T: @ %bb.0:4162; V7A-T-NEXT: movw r1, #40924163; V7A-T-NEXT: and.w r0, r1, r0, lsr #174164; V7A-T-NEXT: bx lr4165;4166; V6M-LABEL: c2_i32:4167; V6M: @ %bb.0:4168; V6M-NEXT: lsrs r1, r0, #174169; V6M-NEXT: ldr r0, .LCPI54_04170; V6M-NEXT: ands r0, r14171; V6M-NEXT: bx lr4172; V6M-NEXT: .p2align 24173; V6M-NEXT: @ %bb.1:4174; V6M-NEXT: .LCPI54_0:4175; V6M-NEXT: .long 4092 @ 0xffc4176 %tmp0 = lshr i32 %arg, 194177 %tmp1 = and i32 %tmp0, 10234178 %tmp2 = shl i32 %tmp1, 24179 ret i32 %tmp24180}4181 4182; The mask covers newly shifted-in bit4183define i32 @c4_i32_bad(i32 %arg) nounwind {4184; V7M-LABEL: c4_i32_bad:4185; V7M: @ %bb.0:4186; V7M-NEXT: mvn r1, #14187; V7M-NEXT: and.w r0, r1, r0, lsr #194188; V7M-NEXT: bx lr4189;4190; V7A-LABEL: c4_i32_bad:4191; V7A: @ %bb.0:4192; V7A-NEXT: mvn r1, #14193; V7A-NEXT: and r0, r1, r0, lsr #194194; V7A-NEXT: bx lr4195;4196; V7A-T-LABEL: c4_i32_bad:4197; V7A-T: @ %bb.0:4198; V7A-T-NEXT: mvn r1, #14199; V7A-T-NEXT: and.w r0, r1, r0, lsr #194200; V7A-T-NEXT: bx lr4201;4202; V6M-LABEL: c4_i32_bad:4203; V6M: @ %bb.0:4204; V6M-NEXT: lsrs r0, r0, #204205; V6M-NEXT: lsls r0, r0, #14206; V6M-NEXT: bx lr4207 %tmp0 = lshr i32 %arg, 194208 %tmp1 = and i32 %tmp0, 163824209 ret i32 %tmp14210}4211 4212; i644213 4214; The most canonical variant4215define i64 @c0_i64(i64 %arg) nounwind {4216; V7M-LABEL: c0_i64:4217; V7M: @ %bb.0:4218; V7M-NEXT: ubfx r0, r1, #19, #104219; V7M-NEXT: movs r1, #04220; V7M-NEXT: bx lr4221;4222; V7A-LABEL: c0_i64:4223; V7A: @ %bb.0:4224; V7A-NEXT: ubfx r0, r1, #19, #104225; V7A-NEXT: mov r1, #04226; V7A-NEXT: bx lr4227;4228; V7A-T-LABEL: c0_i64:4229; V7A-T: @ %bb.0:4230; V7A-T-NEXT: ubfx r0, r1, #19, #104231; V7A-T-NEXT: movs r1, #04232; V7A-T-NEXT: bx lr4233;4234; V6M-LABEL: c0_i64:4235; V6M: @ %bb.0:4236; V6M-NEXT: lsls r0, r1, #34237; V6M-NEXT: lsrs r0, r0, #224238; V6M-NEXT: movs r1, #04239; V6M-NEXT: bx lr4240 %tmp0 = lshr i64 %arg, 514241 %tmp1 = and i64 %tmp0, 10234242 ret i64 %tmp14243}4244 4245; Should be still fine, but the mask is shifted4246define i64 @c1_i64(i64 %arg) nounwind {4247; V7M-LABEL: c1_i64:4248; V7M: @ %bb.0:4249; V7M-NEXT: movw r0, #40924250; V7M-NEXT: and.w r0, r0, r1, lsr #194251; V7M-NEXT: movs r1, #04252; V7M-NEXT: bx lr4253;4254; V7A-LABEL: c1_i64:4255; V7A: @ %bb.0:4256; V7A-NEXT: movw r0, #40924257; V7A-NEXT: and r0, r0, r1, lsr #194258; V7A-NEXT: mov r1, #04259; V7A-NEXT: bx lr4260;4261; V7A-T-LABEL: c1_i64:4262; V7A-T: @ %bb.0:4263; V7A-T-NEXT: movw r0, #40924264; V7A-T-NEXT: and.w r0, r0, r1, lsr #194265; V7A-T-NEXT: movs r1, #04266; V7A-T-NEXT: bx lr4267;4268; V6M-LABEL: c1_i64:4269; V6M: @ %bb.0:4270; V6M-NEXT: lsrs r1, r1, #194271; V6M-NEXT: ldr r0, .LCPI57_04272; V6M-NEXT: ands r0, r14273; V6M-NEXT: movs r1, #04274; V6M-NEXT: bx lr4275; V6M-NEXT: .p2align 24276; V6M-NEXT: @ %bb.1:4277; V6M-NEXT: .LCPI57_0:4278; V6M-NEXT: .long 4092 @ 0xffc4279 %tmp0 = lshr i64 %arg, 514280 %tmp1 = and i64 %tmp0, 40924281 ret i64 %tmp14282}4283 4284; Should be still fine, but the result is shifted left afterwards4285define i64 @c2_i64(i64 %arg) nounwind {4286; V7M-LABEL: c2_i64:4287; V7M: @ %bb.0:4288; V7M-NEXT: movw r0, #40924289; V7M-NEXT: and.w r0, r0, r1, lsr #174290; V7M-NEXT: movs r1, #04291; V7M-NEXT: bx lr4292;4293; V7A-LABEL: c2_i64:4294; V7A: @ %bb.0:4295; V7A-NEXT: movw r0, #40924296; V7A-NEXT: and r0, r0, r1, lsr #174297; V7A-NEXT: mov r1, #04298; V7A-NEXT: bx lr4299;4300; V7A-T-LABEL: c2_i64:4301; V7A-T: @ %bb.0:4302; V7A-T-NEXT: movw r0, #40924303; V7A-T-NEXT: and.w r0, r0, r1, lsr #174304; V7A-T-NEXT: movs r1, #04305; V7A-T-NEXT: bx lr4306;4307; V6M-LABEL: c2_i64:4308; V6M: @ %bb.0:4309; V6M-NEXT: lsrs r1, r1, #174310; V6M-NEXT: ldr r0, .LCPI58_04311; V6M-NEXT: ands r0, r14312; V6M-NEXT: movs r1, #04313; V6M-NEXT: bx lr4314; V6M-NEXT: .p2align 24315; V6M-NEXT: @ %bb.1:4316; V6M-NEXT: .LCPI58_0:4317; V6M-NEXT: .long 4092 @ 0xffc4318 %tmp0 = lshr i64 %arg, 514319 %tmp1 = and i64 %tmp0, 10234320 %tmp2 = shl i64 %tmp1, 24321 ret i64 %tmp24322}4323 4324; The mask covers newly shifted-in bit4325define i64 @c4_i64_bad(i64 %arg) nounwind {4326; V7M-LABEL: c4_i64_bad:4327; V7M: @ %bb.0:4328; V7M-NEXT: mvn r0, #14329; V7M-NEXT: and.w r0, r0, r1, lsr #194330; V7M-NEXT: movs r1, #04331; V7M-NEXT: bx lr4332;4333; V7A-LABEL: c4_i64_bad:4334; V7A: @ %bb.0:4335; V7A-NEXT: mvn r0, #14336; V7A-NEXT: and r0, r0, r1, lsr #194337; V7A-NEXT: mov r1, #04338; V7A-NEXT: bx lr4339;4340; V7A-T-LABEL: c4_i64_bad:4341; V7A-T: @ %bb.0:4342; V7A-T-NEXT: mvn r0, #14343; V7A-T-NEXT: and.w r0, r0, r1, lsr #194344; V7A-T-NEXT: movs r1, #04345; V7A-T-NEXT: bx lr4346;4347; V6M-LABEL: c4_i64_bad:4348; V6M: @ %bb.0:4349; V6M-NEXT: lsrs r0, r1, #204350; V6M-NEXT: lsls r0, r0, #14351; V6M-NEXT: movs r1, #04352; V6M-NEXT: bx lr4353 %tmp0 = lshr i64 %arg, 514354 %tmp1 = and i64 %tmp0, 163824355 ret i64 %tmp14356}4357 4358; ---------------------------------------------------------------------------- ;4359; Constant, storing the result afterwards.4360; ---------------------------------------------------------------------------- ;4361 4362; i324363 4364; The most canonical variant4365define void @c5_i32(i32 %arg, ptr %ptr) nounwind {4366; V7M-LABEL: c5_i32:4367; V7M: @ %bb.0:4368; V7M-NEXT: ubfx r0, r0, #19, #104369; V7M-NEXT: str r0, [r1]4370; V7M-NEXT: bx lr4371;4372; V7A-LABEL: c5_i32:4373; V7A: @ %bb.0:4374; V7A-NEXT: ubfx r0, r0, #19, #104375; V7A-NEXT: str r0, [r1]4376; V7A-NEXT: bx lr4377;4378; V7A-T-LABEL: c5_i32:4379; V7A-T: @ %bb.0:4380; V7A-T-NEXT: ubfx r0, r0, #19, #104381; V7A-T-NEXT: str r0, [r1]4382; V7A-T-NEXT: bx lr4383;4384; V6M-LABEL: c5_i32:4385; V6M: @ %bb.0:4386; V6M-NEXT: lsls r0, r0, #34387; V6M-NEXT: lsrs r0, r0, #224388; V6M-NEXT: str r0, [r1]4389; V6M-NEXT: bx lr4390 %tmp0 = lshr i32 %arg, 194391 %tmp1 = and i32 %tmp0, 10234392 store i32 %tmp1, ptr %ptr4393 ret void4394}4395 4396; Should be still fine, but the mask is shifted4397define void @c6_i32(i32 %arg, ptr %ptr) nounwind {4398; V7M-LABEL: c6_i32:4399; V7M: @ %bb.0:4400; V7M-NEXT: ubfx r0, r0, #19, #124401; V7M-NEXT: str r0, [r1]4402; V7M-NEXT: bx lr4403;4404; V7A-LABEL: c6_i32:4405; V7A: @ %bb.0:4406; V7A-NEXT: ubfx r0, r0, #19, #124407; V7A-NEXT: str r0, [r1]4408; V7A-NEXT: bx lr4409;4410; V7A-T-LABEL: c6_i32:4411; V7A-T: @ %bb.0:4412; V7A-T-NEXT: ubfx r0, r0, #19, #124413; V7A-T-NEXT: str r0, [r1]4414; V7A-T-NEXT: bx lr4415;4416; V6M-LABEL: c6_i32:4417; V6M: @ %bb.0:4418; V6M-NEXT: lsls r0, r0, #14419; V6M-NEXT: lsrs r0, r0, #204420; V6M-NEXT: str r0, [r1]4421; V6M-NEXT: bx lr4422 %tmp0 = lshr i32 %arg, 194423 %tmp1 = and i32 %tmp0, 40954424 store i32 %tmp1, ptr %ptr4425 ret void4426}4427 4428; Should be still fine, but the result is shifted left afterwards4429define void @c7_i32(i32 %arg, ptr %ptr) nounwind {4430; V7M-LABEL: c7_i32:4431; V7M: @ %bb.0:4432; V7M-NEXT: movw r2, #40924433; V7M-NEXT: and.w r0, r2, r0, lsr #174434; V7M-NEXT: str r0, [r1]4435; V7M-NEXT: bx lr4436;4437; V7A-LABEL: c7_i32:4438; V7A: @ %bb.0:4439; V7A-NEXT: movw r2, #40924440; V7A-NEXT: and r0, r2, r0, lsr #174441; V7A-NEXT: str r0, [r1]4442; V7A-NEXT: bx lr4443;4444; V7A-T-LABEL: c7_i32:4445; V7A-T: @ %bb.0:4446; V7A-T-NEXT: movw r2, #40924447; V7A-T-NEXT: and.w r0, r2, r0, lsr #174448; V7A-T-NEXT: str r0, [r1]4449; V7A-T-NEXT: bx lr4450;4451; V6M-LABEL: c7_i32:4452; V6M: @ %bb.0:4453; V6M-NEXT: lsrs r0, r0, #174454; V6M-NEXT: ldr r2, .LCPI62_04455; V6M-NEXT: ands r2, r04456; V6M-NEXT: str r2, [r1]4457; V6M-NEXT: bx lr4458; V6M-NEXT: .p2align 24459; V6M-NEXT: @ %bb.1:4460; V6M-NEXT: .LCPI62_0:4461; V6M-NEXT: .long 4092 @ 0xffc4462 %tmp0 = lshr i32 %arg, 194463 %tmp1 = and i32 %tmp0, 10234464 %tmp2 = shl i32 %tmp1, 24465 store i32 %tmp2, ptr %ptr4466 ret void4467}4468 4469; i644470 4471; The most canonical variant4472define void @c5_i64(i64 %arg, ptr %ptr) nounwind {4473; V7M-LABEL: c5_i64:4474; V7M: @ %bb.0:4475; V7M-NEXT: movs r0, #04476; V7M-NEXT: ubfx r1, r1, #19, #104477; V7M-NEXT: strd r1, r0, [r2]4478; V7M-NEXT: bx lr4479;4480; V7A-LABEL: c5_i64:4481; V7A: @ %bb.0:4482; V7A-NEXT: mov r0, #04483; V7A-NEXT: str r0, [r2, #4]4484; V7A-NEXT: ubfx r0, r1, #19, #104485; V7A-NEXT: str r0, [r2]4486; V7A-NEXT: bx lr4487;4488; V7A-T-LABEL: c5_i64:4489; V7A-T: @ %bb.0:4490; V7A-T-NEXT: movs r0, #04491; V7A-T-NEXT: ubfx r1, r1, #19, #104492; V7A-T-NEXT: strd r1, r0, [r2]4493; V7A-T-NEXT: bx lr4494;4495; V6M-LABEL: c5_i64:4496; V6M: @ %bb.0:4497; V6M-NEXT: movs r0, #04498; V6M-NEXT: lsls r1, r1, #34499; V6M-NEXT: lsrs r1, r1, #224500; V6M-NEXT: str r1, [r2]4501; V6M-NEXT: str r0, [r2, #4]4502; V6M-NEXT: bx lr4503 %tmp0 = lshr i64 %arg, 514504 %tmp1 = and i64 %tmp0, 10234505 store i64 %tmp1, ptr %ptr4506 ret void4507}4508 4509; Should be still fine, but the mask is shifted4510define void @c6_i64(i64 %arg, ptr %ptr) nounwind {4511; V7M-LABEL: c6_i64:4512; V7M: @ %bb.0:4513; V7M-NEXT: movs r0, #04514; V7M-NEXT: ubfx r1, r1, #19, #124515; V7M-NEXT: strd r1, r0, [r2]4516; V7M-NEXT: bx lr4517;4518; V7A-LABEL: c6_i64:4519; V7A: @ %bb.0:4520; V7A-NEXT: mov r0, #04521; V7A-NEXT: str r0, [r2, #4]4522; V7A-NEXT: ubfx r0, r1, #19, #124523; V7A-NEXT: str r0, [r2]4524; V7A-NEXT: bx lr4525;4526; V7A-T-LABEL: c6_i64:4527; V7A-T: @ %bb.0:4528; V7A-T-NEXT: movs r0, #04529; V7A-T-NEXT: ubfx r1, r1, #19, #124530; V7A-T-NEXT: strd r1, r0, [r2]4531; V7A-T-NEXT: bx lr4532;4533; V6M-LABEL: c6_i64:4534; V6M: @ %bb.0:4535; V6M-NEXT: movs r0, #04536; V6M-NEXT: lsls r1, r1, #14537; V6M-NEXT: lsrs r1, r1, #204538; V6M-NEXT: str r1, [r2]4539; V6M-NEXT: str r0, [r2, #4]4540; V6M-NEXT: bx lr4541 %tmp0 = lshr i64 %arg, 514542 %tmp1 = and i64 %tmp0, 40954543 store i64 %tmp1, ptr %ptr4544 ret void4545}4546 4547; Should be still fine, but the result is shifted left afterwards4548define void @c7_i64(i64 %arg, ptr %ptr) nounwind {4549; V7M-LABEL: c7_i64:4550; V7M: @ %bb.0:4551; V7M-NEXT: movs r0, #04552; V7M-NEXT: movw r3, #40924553; V7M-NEXT: and.w r1, r3, r1, lsr #174554; V7M-NEXT: strd r1, r0, [r2]4555; V7M-NEXT: bx lr4556;4557; V7A-LABEL: c7_i64:4558; V7A: @ %bb.0:4559; V7A-NEXT: movw r0, #40924560; V7A-NEXT: mov r3, #04561; V7A-NEXT: and r0, r0, r1, lsr #174562; V7A-NEXT: stm r2, {r0, r3}4563; V7A-NEXT: bx lr4564;4565; V7A-T-LABEL: c7_i64:4566; V7A-T: @ %bb.0:4567; V7A-T-NEXT: movs r0, #04568; V7A-T-NEXT: movw r3, #40924569; V7A-T-NEXT: and.w r1, r3, r1, lsr #174570; V7A-T-NEXT: strd r1, r0, [r2]4571; V7A-T-NEXT: bx lr4572;4573; V6M-LABEL: c7_i64:4574; V6M: @ %bb.0:4575; V6M-NEXT: movs r0, #04576; V6M-NEXT: lsrs r1, r1, #174577; V6M-NEXT: ldr r3, .LCPI65_04578; V6M-NEXT: ands r3, r14579; V6M-NEXT: str r3, [r2]4580; V6M-NEXT: str r0, [r2, #4]4581; V6M-NEXT: bx lr4582; V6M-NEXT: .p2align 24583; V6M-NEXT: @ %bb.1:4584; V6M-NEXT: .LCPI65_0:4585; V6M-NEXT: .long 4092 @ 0xffc4586 %tmp0 = lshr i64 %arg, 514587 %tmp1 = and i64 %tmp0, 10234588 %tmp2 = shl i64 %tmp1, 24589 store i64 %tmp2, ptr %ptr4590 ret void4591}4592