Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // by MySoft irc freenode #asm
- // *** Constants For ASM (as we normally do for MMX/SSE) ***
- u32 iRGBMask = 0b01110001100011100111000110001110 //RGB Component Mask
- u32 iSHMask = 0b00000100001000010000010000100000 //Shield Component Mask
- u32 iCRGMask = 0b10000000000100001000000000010000 //Carry Red/Green Mask
- u32 iCBMask = 0b00000010000000000000001000000000 //Carry Blue Mask
- // ======== Code in C ========
- // 'Average with round to source (6.3ms Nintendo DS -O fast)
- void Alpha50_C( u32* pTGT, u32* PSRC, int iPixelCount ) {
- // RRRGGGBBrrrgggbbRRRGGGBBrrrgggbb
- #define _RGB1_ 0b01110001100011100111000110001110u
- #define _RGB1x_ 0b11100011000111001110001100011100u
- #define _SHLD_ 0b00000100001000010000010000100000u
- #define _cRG1_ 0b10000000000100001000000000010000u
- #define _cB1_ 0b00000010000000000000001000000000u
- #define _RGB2_ 0b00011100111000110001110011100011u
- #define _RGB2x_ 0b00111001110001100011100111000110u
- #define _cRG2_ 0b01000010000000000100001000000000u
- #define _cB2_ 0b00000000000010000000000000001000u
- u32 s1,s2,tg;
- int CNT;
- for ( CNT=0 ; CNT<(iPixelCount>>2) ; CNT++ ) {
- if ( pTGT[CNT] != pSRC[CNT] ) {
- // *** Mask 1 ***
- s1 = (pTGT[CNT] >> 1) & _RGB1_;
- s2 = (pSRC[CNT] >> 1) & _RGB1_;
- s1 = (s1+s2) & _RGB1x_;
- s1 = (s1 >> 1) | _SHLD_;
- s2 = s1-s2; //(carry check)
- tg = ((s1 &_RGB1_)+((s2 & _cRG1_) >> 3)+((s2 & _cB1_) >> 2)) << 1;
- // *** Mask 2 ***
- s1 = pTGT[CNT] & _RGB2_;
- s2 = pSRC[CNT] & _RGB2_;
- s1 = ((s1+s2) & _RGB2x_) | _SHLD_;
- s2 = s1-(s2 shl 1)
- pTGT[CNT] = tg | (((s1 & _RGB2x_) +
- (((s2 & _cRG2_) >> 3)+((s2 & _cB2_) >> 2))) >> 1)
- }
- }
- }
- // ========= Code o Optimized in Nintendo DS ASM ========
- // 'Average with bonus towards source (~4.4ms (~5.3ms without unrolling))
- void Alpha50_ASM ( u32* pTGT, u32* PSRC, int iPixelCount ) {
- asm { 'Variable Loading Block
- ldr r0, $pTGT 'Target Pointer
- ldr r1, $pSRC 'Source Pointer
- ldr r2, $iPixelCount 'How Many pixels to process?
- ldr r3, $iCBMask 'Carry Mask for Blue
- ldr r10, $iRGBMask 'Mask 'R0B0G0R0B0G0' / '0G0R0B0G0R0B'
- ldr r11, $iSHMask 'Shield Mask (component shield)
- ldr r12, $iCRGMask 'Carry Mask for Red/Green
- }
- asm { 'Alpha50% with source boost
- mov r2, r2, asr #3 'We're processing 8! pixels each time
- str r14, [r13,#-4]! 'Save r14(link) on stack
- 'str r13, 9f 'save r13 (stack) on data inside code...
- mov r14, r3 'Now that r14 is safe use it as 'carry' mask
- sub r0, #4
- sub r1, #4
- 0: 'processing pixels
- ldmia r0 !, {r3,r8} 'loading 8 pixels targer and position ahead
- ldmia r1 !, {r4,r9} 'loading 4 pixels source and position ahead
- cmp r3, r4 'Are src/tgt pixels equal?
- beq 1f 'yes? skip processing
- ' --- Mask1 ---
- and r5, r10, r3, lsr #1 'mask RGB and shift right (tgt) 'R5:0RRR000BB000GGG00RRR000BB000GGG0
- and r6, r10, r4, lsr #1 'mask RGB and shift right (src) 'R6:0RRR000BB000GGG00RRR000BB000GGG0
- add r5, r6 'add both halved values 'R5:RRRR00BBB00GGGG0RRRR00BBB00GGGG0
- and r5, r10, lsl #1 'only Mask RGB bits 'R5:RRR000BB000GGG00RRR000BB000GGG00
- orr r5, r11, r5, lsr #1 'Shield components (overflow) 'R5:0RRR010BB010GGG10RRR010BB010GGG0
- sub r6, r5, r6 'temp = tgt-src (carry check) 'R6:c???00c??00c???0c???00c??00c???0
- and r5, r10 'only Mask RGB bits 'R5:0RRR000BB000GGG00RRR000BB000GGG0
- and r7, r6, r12 'keep carry of RG's 'R8:c0000000000c0000c0000000000c0000
- and r6, r14 'keep carry of B's 'R6:000000c000000000000000c000000000
- add r7, r5, r7, lsr #3 'sum tgt+carry (RG's) 'R7:0RRr000BB000GGg00RRr000BB000GGg0
- add r7, r6, lsr #2 'sum carry (B's) 'R7:0RRr000Bb000GGg00RRr000Bb000GGg0
- mov r7, r7, lsl #1 'adjust sum to correct place 'R7:RRr000Bb000GGg00RRr000Bb000GGg00
- ' --- Mask2 ---
- and r5, r3, r10, ror #7 'mask2 RGB (tgt) 'R5:000GGG00RRR000BB000GGG00RRR000BB
- and r6, r4, r10, ror #7 'mask2 RGB (src) 'R6:000GGG00RRR000BB000GGG00RRR000BB
- add r5, r6 'add values (no 32bit overflow) 'R5:00GGGG0RRRR00BBB00GGGG0RRRR00BBB
- and r5, r10, ror #6 'only Mask2 bits (lsl 1) 'R5:00GGG00RRR000BB000GGG00RRR000BB0
- orr r5, r11 'AVG and Shield (overflow) 'R5:00GGG10RRR100BB100GGG10RRR100BB0
- sub r6, r5, r6, lsl #1 'temp = tgt-src (carry check) 'R6:cc???0c???0cc??0cc???0c???0cc??0
- and r5, r10, ror #6 'only Mask2 component bits 'R5:00GGG00RRR000BB000GGG00RRR000BB0
- and r3, r6, r12, ror #6 'keep carry of RG's 'R8:0c0000c0000000000c0000c000000000
- and r6, r14, ror #6 'keep carry of B's 'R6:000000000000c000000000000000c000
- add r5, r3, lsr #3 'add tgt+carry (RG's) 'R5:00GGg00RRr000BB000GGg00RRr000BB0
- add r5, r6, lsr #2 'add tgt+carry (B's) 'R5:00GGg00RRr000Bb000GGg00RRr000Bb0
- orr r7, r5, lsr #1 'store mask on correct place 'R7:RRrGGgBbRRrGGgBbRRrGGgBbRRrGGgBb
- str r7, [r0,#-8] 'store first 4 pixels
- 1: 'now unrolling the loop...
- cmp r8, r9 'Are src/tgt pixels equal?
- beq 1f 'yes? skip processing
- ' --- Mask1 ---
- and r5, r10, r8, lsr #1 'mask RGB and shift right (tgt) 'R5:0RRR000BB000GGG00RRR000BB000GGG0
- and r6, r10, r9, lsr #1 'mask RGB and shift right (src) 'R6:0RRR000BB000GGG00RRR000BB000GGG0
- add r5, r6 'add both halved values 'R5:RRRR00BBB00GGGG0RRRR00BBB00GGGG0
- and r5, r10, lsl #1 'only Mask RGB bits 'R5:RRR000BB000GGG00RRR000BB000GGG00
- orr r5, r11, r5, lsr #1 'Shield components (overflow) 'R5:0RRR010BB010GGG10RRR010BB010GGG0
- sub r6, r5, r6 'temp = tgt-src (carry check) 'R6:c???00c??00c???0c???00c??00c???0
- and r5, r10 'only Mask RGB bits 'R5:0RRR000BB000GGG00RRR000BB000GGG0
- and r7, r6, r12 'keep carry of RG's 'R8:c0000000000c0000c0000000000c0000
- and r6, r14 'keep carry of B's 'R6:000000c000000000000000c000000000
- add r7, r5, r7, lsr #3 'sum tgt+carry (RG's) 'R7:0RRr000BB000GGg00RRr000BB000GGg0
- add r7, r6, lsr #2 'sum carry (B's) 'R7:0RRr000Bb000GGg00RRr000Bb000GGg0
- mov r7, r7, lsl #1 'adjust sum to correct place 'R7:RRr000Bb000GGg00RRr000Bb000GGg00
- ' --- Mask2 ---
- and r5, r8, r10, ror #7 'mask2 RGB (tgt) 'R5:000GGG00RRR000BB000GGG00RRR000BB
- and r6, r9, r10, ror #7 'mask2 RGB (src) 'R6:000GGG00RRR000BB000GGG00RRR000BB
- add r5, r6 'add values (no 32bit overflow) 'R5:00GGGG0RRRR00BBB00GGGG0RRRR00BBB
- and r5, r10, ror #6 'only Mask2 bits (lsl 1) 'R5:00GGG00RRR000BB000GGG00RRR000BB0
- orr r5, r11 'AVG and Shield (overflow) 'R5:00GGG10RRR100BB100GGG10RRR100BB0
- sub r6, r5, r6, lsl #1 'temp = tgt-src (carry check) 'R6:cc???0c???0cc??0cc???0c???0cc??0
- and r5, r10, ror #6 'only Mask2 component bits 'R5:00GGG00RRR000BB000GGG00RRR000BB0
- and r3, r6, r12, ror #6 'keep carry of RG's 'R8:0c0000c0000000000c0000c000000000
- and r6, r14, ror #6 'keep carry of B's 'R6:000000000000c000000000000000c000
- add r5, r3, lsr #3 'add tgt+carry (RG's) 'R5:00GGg00RRr000BB000GGg00RRr000BB0
- add r5, r6, lsr #2 'add tgt+carry (B's) 'R5:00GGg00RRr000Bb000GGg00RRr000Bb0
- orr r7, r5, lsr #1 'store mask on correct place 'R7:RRrGGgBbRRrGGgBbRRrGGgBbRRrGGgBb
- str r7, [r0,#-4] 'store next 4 pixels
- 1: 'done with pixels
- subs r2, #1 '8 pixels done there are more?
- bne 0b 'yes? then go process them!
- 'b 1f 'skip data in code
- '9: .word 0 ' here goes r13 upon return
- '1: ldr r13, 9b 'restore r13 (stack)
- ldmia r13 !, {r14} 'restore saved r13
- ' --- DONE! ---
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment