30 April 2021, 08:49 | #1 |
Registered User
Join Date: Jan 2019
Location: Brisbane
Posts: 99
|
Bits set
Hi folks,
Just wondering if there is a better/tricker/hidden/black book approach to testing if some bit combo is set. I am trying to replace a cases of multiple compares against word variables in my code. So I planned to change to use a 32bit var to hold bits as flags for various state, like (0)enabled, (1)visible, (2)etc, and have them enumerated as such. I need all 32 bits and the code is a little bit generic so using longs. Old code had - Stuff like this just for example... Code:
cmp.b #1,obj_visible(ax) bne .exit cmp.b #1,obj_enabled(ax) bne .exit ; update and draw The Code:
cmp.l #(1<<0)|(1<<1),d0 Code:
; Test bit flags ;moveq.l #0,d0 ; No bits are set (works) ;move.l #(1<<0),d0 ; Set bit 0 (works) ;move.l #(1<<1),d0 ; Set bit 1 (works) ;move.l #(1<<0)|(1<<1),d0 ; Set bit 0 and 1 (works) move.l #(1<<0)|(1<<1)|(1<<2),d0 ; Set bit 0 and 1 and 2 (works) ; Test if these bits 0 and 1 are set andi.l #(1<<0)|(1<<1),d0 cmp.l #(1<<0)|(1<<1),d0 sub.l #(1<<0)|(1<<1),d0 ; replace cmp.l with sub.l saves 8 cycles. Making it slightly faster than two individual compares. beq .theseBitsAreSet ; Both bits are not set move.l #-100,d0 rts .theseBitsAreSet move.l #100,d0 rts Last edited by Auscoder; 30 April 2021 at 09:11. |
30 April 2021, 09:51 | #2 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
In your specific case (3 bits), could be as simple as:
Code:
btst d0,#%11111110 bne .theseBitsAreSet ; bits 1 or 2 or 3 are not set move.l #-100,d0 rts .theseBitsAreSet move.l #100,d0 rts |
30 April 2021, 09:54 | #3 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,322
|
For your first example, you can just have these two bits in same byte.
And instead of having to check if these are both set, compare them with 0 by reversing their meaning : Code:
tst.b obj_state(ax) bne .exit If you only have 2 bits and not all possible combinations need to be checked, you can use the following method (use sign bit and any other like b0, keeping all other bits =0) : Code:
tst.b obj_state(ax) bne .xx ; $01, $80, $81 beq .xx ; $00 bpl .xx ; $00, $01 bmi .xx ; $80, $81 bgt .xx ; $01 ble .xx ; $00, $80 That may be a big part of the problem... |
30 April 2021, 10:17 | #4 |
Lemon. / Core Design
Join Date: Mar 2016
Location: Tier 5
Posts: 1,209
|
You just need to do this:
Code:
; Test if these bits 0 and 1 are set andi.l #(1<<0)|(1<<1),d0 beq .theseBitsAreNotSet |
30 April 2021, 10:23 | #5 |
Registered User
Join Date: Jan 2019
Location: Brisbane
Posts: 99
|
|
30 April 2021, 10:25 | #6 |
Registered User
Join Date: Feb 2020
Location: Germany
Posts: 177
|
I found the following interesting article.
|
30 April 2021, 10:52 | #7 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,038
|
If you are testing for multiple bits, as pointed out, it's better to use reverse logic (0 = flag is set) and test for a zero.
One way to optimize and simplify this is to use macros instead, and there you can do all kind of stuff: check if all the flags of interest are in the lower or the upper byte/word and only do an 8/16-bit check, maybe use moveq if they fit in 7 bits, check if it's only a single flag and do a btst, ... For example, I use macros to set/clear/test for a single bit in a 32-bit mask, so I don't have to bother thinking which byte of the 4 is it (mem ops are 8-bit). Multi-bits would of course be more complex, it depends how much important is the cycle count. |
30 April 2021, 10:54 | #8 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
Just move to a spare register
Something like this: Code:
moveq #%111,d1 and.l d0,d1 bne .theseBitsAreSet EDIT: or even faster on vanilla 68k: and.w d0,d1 Of course this also has its limits. You have to adapt your code to your needs. Last edited by ross; 30 April 2021 at 11:27. Reason: reversed d1 and d0 :) |
02 May 2021, 10:03 | #9 | |
Registered User
Join Date: Jan 2019
Location: Brisbane
Posts: 99
|
Z will be cleared if any of tested bits is set. I want to confirm all bits of interest are set. Others can be set or not, not a problem. But src bits all must be set. So I ended up explaining it very badly I think. I hope this clears it up.
Code:
; Any bits could be set (example 7 and 15 or more...) move.l #(1<<7)|(1<<15),d0 andi.l #(1<<1)|(1<<2),d0 ; z set if none of the bits 1|2 are set (dest == 0) move.l #(1<<7)|(1<<15),d0 andi.l #(1<<2)|(1<<7),d0 ; z cleared if *any* bits 2|7 are set (dest != 0) sub.l #(1<<2)|(1<<7),d0 ; validates both are set if dest == 0 move.l #(1<<7)|(1<<15)|(1<<18),d0 ; must handle arbitrary bits set andi.l #(1<<7)|(1<<18),d0 ; z cleared when both are set (good) Quote:
Last edited by Auscoder; 02 May 2021 at 10:13. Reason: Explain 3rd case better |
|
02 May 2021, 10:39 | #10 |
Registered User
Join Date: Aug 2010
Location: Italy
Posts: 787
|
If, as suggested, you can use reverse logic:
andi.l #<BitsToCheck>,d0 beq(.b) AllBitsOn Otherwise: move(q).l #<BitsToCheck>,d1 and.l d1,d0 cmp.l d1,d0 beq(.b) AllBitsOn |
02 May 2021, 10:48 | #11 |
Registered User
Join Date: Jan 2019
Location: Brisbane
Posts: 99
|
Sounds like the trick I am looking for, thanks to all those that mentioned it. Also the bit set testing I’ll have a look at JoeJoe and others. Now just need to wrap my head around it. For reverse logic takes a bit of good old fashioned paper and pen for it to click with me.
|
02 May 2021, 12:16 | #12 |
Registered User
Join Date: Jan 2019
Location: Brisbane
Posts: 99
|
Code:
move.l #$ffffffff,d0 bclr.l #7,d0 bclr.l #15,d0 andi.l #(1<<7)|(1<<2),d0 ; z is clear move.l #$ffffffff,d0 bclr.l #7,d0 bclr.l #15,d0 andi.l #(1<<7)|(1<<18),d0 ; z is clear move.l #-1,d0 bclr.l #7,d0 bclr.l #15,d0 bclr.l #18,d0 andi.l #(1<<7)|(1<<15),d0 ; z is set |
02 May 2021, 14:05 | #13 | |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,322
|
Quote:
If this isn't acceptable, you can also do : Code:
move(q).l #~<BitsToCheck>,d1 or.l d0,d1 addq.l #1,d1 beq(.b) AllBitsOn Last edited by meynaf; 02 May 2021 at 14:30. |
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Some very rare bits available | Ricardo | Coders. Asm / Hardware | 1 | 18 March 2014 20:31 |
WinUAE 2.7.0 64 Bits | freddy | support.WinUAE | 10 | 12 December 2013 22:40 |
Need a few bits - can anyone help? | Rabbit80 | MarketPlace | 0 | 11 October 2008 22:16 |
BITS demos. | SoLo2 | support.Demos | 64 | 19 September 2008 19:42 |
Old Bits wanted please ---> | ElectroBlaster | MarketPlace | 0 | 06 September 2003 00:24 |
|
|