Direct flag manipulation in assembler (errors noted)
Phil Pilgrim (PhiPi)
Posts: 23,514
Occasionally, it's handy to be able to manipulate the z and c flags directly, without causing other side effects or relying on externally-defined longs. This is often done at the end of a subroutine to return a status or error condition, which the calling program can then check. Herewith is what I came up with for various sets, clears, copies, and complements, plus some saves and restores. Each uses its own instruction as a source of known destination data, which provides the necessary bits for flag manipulation.
These are, so far, untested. My confidence that they will work is based solely on my trust in the Parallax documentation for these instructions (and my ability to understand it ). If the assembler supported macros, these could be defined as such. Otherwise, it wouldn't be the worst idea in the world to include them as native instructions. (The items left as exercises probably can't be done in the same spirit as single instructions and without auxiliary longs.)
-Phil
Update: Thanks to mpark for correcting my spelling via private communication. (He needn't have worried about embarrassing me online, though. I have a pretty thick skin.) I had spelled "exercise" as "exercize", thinking that the two were British and American variants, respectively. But unlike many such words, "exercise" doesn't have an Americanized (Americanised?) equivalent.
Post Edited (Phil Pilgrim (PhiPi)) : 3/3/2010 7:08:07 PM GMT
set_z test $,#0 wz 'Instr = %01100010011111$$$$$$$$$000000000 z = result (instr & 0) == 0 set_nz test $,#1 wz 'Instr = %01100010011111$$$$$$$$$000000001 z = result (instr & 1) == 1 set_c test $,#1 wc 'Instr = %01100001011111$$$$$$$$$000000001 c = parity (instr & 1) == 1 set_nc test $,#0 wc 'Instr = %01100001011111$$$$$$$$$000000000 c = parity (instr & 0) == 0 set_z_c shr $,#31 wz,wc,nr 'Instr = %00101011011111$$$$$$$$$000011111 z = result (instr >> 31) == 0, c = instr.0 == 1 set_z_nc shr $,#30 wz,wc,nr 'Instr = %00101011011111$$$$$$$$$000011110 z = result (instr >> 30) == 0, c = instr.0 == 0 set_nz_c shr $,#1 wz,wc,nr 'Instr = %00101011011111$$$$$$$$$000000001 z = result (instr >> 1) <> 0, c = instr.0 == 1 set_nz_nc shr $,#2 wz,wc,nr 'Instr = %00101011011111$$$$$$$$$000000010 z = result (instr >> 2) <> 0, c = instr.0 == 0 [s]mov_z_c muxnc $,#1 wz,nr 'Instr = %01110110011111$$$$$$$$$000000001 z = result (nc & instr & 1) == c mov_z_nc muxc $,#1 wz,nr 'Instr = %01110010011111$$$$$$$$$000000001 z = result (c & 1) == nc mov_c_z muxz $,#1 wc,nr 'Instr = %01111001011111$$$$$$$$$000000001 c = parity (z & 1) == nz mov_c_nz muxnz $,#1 wc,nr 'Instr = %01111101011111$$$$$$$$$000000001 c = parity (nz & 1) == nz[/s] swap_z_c 'Left as an exercise for the reader. [s]not_z muxz $,#1 wz,nr 'Instr = %01111010011111$$$$$$$$$000000001 z = result (z & 1) == nz not_c muxnc $,#1 wc,nr 'Instr = %01110101011111$$$$$$$$$000000001 c = parity (nc & 1) == nc[/s] save_z muxnz restore_z,#1 restore_z test $,#1 wz 'Instr = %01100010011111$$$$$$$$$00000000[s]z[/s] z = result (instr & nz) == z save_c muxc restore_c,#1 restore_c test $,#1 wc 'Instr = %01100001011111$$$$$$$$$00000000c c = parity (instr & c) == c save_z_c 'Left as an exercise for the reader. restore_z_c 'Left as an exercise for the reader.
These are, so far, untested. My confidence that they will work is based solely on my trust in the Parallax documentation for these instructions (and my ability to understand it ). If the assembler supported macros, these could be defined as such. Otherwise, it wouldn't be the worst idea in the world to include them as native instructions. (The items left as exercises probably can't be done in the same spirit as single instructions and without auxiliary longs.)
-Phil
Update: Thanks to mpark for correcting my spelling via private communication. (He needn't have worried about embarrassing me online, though. I have a pretty thick skin.) I had spelled "exercise" as "exercize", thinking that the two were British and American variants, respectively. But unlike many such words, "exercise" doesn't have an Americanized (Americanised?) equivalent.
Post Edited (Phil Pilgrim (PhiPi)) : 3/3/2010 7:08:07 PM GMT
Comments
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
Suzuki SV1000S motorcycle
-Phil
Post Edited (kuroneko) : 4/2/2010 9:15:44 AM GMT
-Phil
I need to be able to set and/or clear the carry and zero flags in LMM.
In LMM using $ doesn't work, because it is usually greater than $1FF and it doesn't point to the instruction anyway.
Any ideas ?
I "think" [noparse][[/noparse] cmpsub 0,0 WC,NR ] will work to set the carry in both native and LMM. Yes·?
Bean
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Use BASIC on the Propeller with the speed of assembly language.
PropBASIC thread http://forums.parallax.com/showthread.php?p=867134
March 2010 Nuts and Volts article·http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp5.pdf
NEW PropBasic Blog: http://propbasic.blogspot.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
There are two rules in life:
· 1) Never divulge all information
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you choose not to decide, you still have made a choice. [noparse][[/noparse]RUSH - Freewill]
For clearing this will do
Do you need combined settings as well?
I haven't found a location independent way for nz_c (yet)a. But most of the time par's shadow is unused so
works just fine. Having said that, if you can't locate a reliable non-NULL register in your setup then that's really sad indeed (there must be some code in there somewhere).
a But I figured out that mov[noparse][[/noparse]dis] sets C with unsigned borrow (D<S).