These new instructions take about the same number of gates as the old ones did.
Wow... really, Wahoo !!!!!
I was worried these may carry a cost...
This change will free a lot of COG memory, which is the most constrained resource in P2.
It also makes PLC type control operations easier to code, and smaller and faster...
I figured we could use "\" to separate the register and bit number for bit addresses. This allows a comma to separate the flag operand.
That reads like it could be an operation, but I can understand multiple commas is less than ideal.
If you want a separator, why not just use the existing convention, which is a decimal point ?
(This also follows HLL conventions for record extraction)
ie Register.BitNumber is the common way this detail is managed on 8051 & others, and usually Boolean Vars are declared
like this
RED_LED_P12 BIT P1.2
RED_LED_P12 BIT BitAdrReg.Number
and then that clear single boolean name is used, as in
MOVB CF, RED_LED_P12
so there is usually no separator visible in the code, but this is also legal in P2
We're already using \ to signal absolute/relative jumps (unless you've taken the suggestion that different mnemonics be used for those)? Could we find something else to separate the D and S, like forward slash or colon? Or even writing D[#1] (which would kind of follow the OUTA[] syntax)?
We're already using \ to signal absolute/relative jumps (unless you've taken the suggestion that different mnemonics be used for those)? Could we find something else to separate the D and S, like forward slash or colon? Or even writing D[#1] (which would kind of follow the OUTA[] syntax)?
I'm lukewarm on \ too, but understand Chip's desire to avoid comma, see my post above (when it arrives via the forum queue...)
The existing convention out there, is a decimal point separator, easiest to just use that.
Some have an aversion to _, and it does need multiple fingers...
I'm fine with the simple C and Z, as they are going to be used a lot, and I recall a Prof, who marked down anyone who used single-variable letters as names....
Also note, the form is not just not-carry, but not-bit is allowed too, which requires some 'not prefix'.
!CF is also fine, tho if I were writing the assembler, I'd also include the likely candidates of ~BitName and NOT Bitname
NOT will likely already be supported in boolean expression evaluation in HLL
Some of those instructions looks overcomplicated to me. How about:
Err, no... The B suffix operators are ALL BOOLEAN ones, that take a BIT variable
CF and ZF are simply reserved special case boolean locations.
Far from being 'overcomplicated', this is actually a very simple subgroup.
ADDC on the other hand, ADDs a 32b operand with carry, and includes the carry flag in the operator.
ie Very different, and it would be confusing to try to merge the two semantics.
This will all be clearer when Chip adds the operation equations to the mnemonics.
Yes, The fact that these are bit operations is more important and relevant
These new instructions take about the same number of gates as the old ones did.
Wow... really, Wahoo !!!!!
I was worried these may carry a cost...
This change will free a lot of COG memory, which is the most constrained resource in P2.
It also makes PLC type control operations easier to code, and smaller and faster...
I figured we could use "\" to separate the register and bit number for bit addresses. This allows a comma to separate the flag operand.
That reads like it could be an operation, but I can understand multiple commas is less than ideal.
If you want a separator, why not just use the existing convention, which is a decimal point ?
(This also follows HLL conventions for record extraction)
ie Register.BitNumber is the common way this detail is managed on 8051 & others, and usually Boolean Vars are declared
like this
RED_LED_P12 BIT P1.2
RED_LED_P12 BIT BitAdrReg.Number
and then that clear single boolean name is used, as in
MOVB CF, RED_LED_P12
so there is usually no separator visible in the code, but this is also legal in P2
MOVB CF, INB.12
MOVB CF, INB.BitPointer
I think the decimal convention should be followed here; it's common practice elsewhere and there's no chance of it being confused for a float operation.
For the toolset, it might be worth considering a simple method of packing multiple bit variables into a single long without the programmer making the bit allocations directly.
...
For the toolset, it might be worth considering a simple method of packing multiple bit variables into a single long without the programmer making the bit allocations directly.
Yes, that's a good idea, so I checked what the 8051 Assembler here allows, this format seems ok
dseg at 0020h
0020 BBa0: ds 1 ; Bits 0..7
0021 VComCtr: ds 1 ; Bits 8..f
;OneMore: ds 1 ; check bseg moves ?
0022 BifFieldsBase: ds 1 ; Start of Boolean base
B 00 Reverse BIT BBa0.0
; bseg at (BifFieldsBase-20H)*8 ; Works, for correct 10h,11h
bseg at BifFieldsBase.0 ; cleaner, 10h,11h correct
0010 bseg_f: dbit 1
0011 bseg_s: dbit 1
0012 bseg_t: dbit 1
0157 D2 10 SETB bseg_f
0159 B2 11 CPL bseg_s
Seems that can "pack multiple bit variables into a multiple bytes single long without the programmer making the bit allocations directly".
Pushing it further with this more complex test ....
; bseg at (BifFieldsBase-20H)*8 ; Works, for correct 10h,11h
bseg at BifFieldsBase.0 ; cleaner, 10h,11h correct
0010 bseg_f: dbit 1
0011 bseg_s: dbit 2
0013 bseg_t: dbit 3
0016 bseg_o6: dbit 1
0017 bseg_o7: dbit 1
0018 bseg_o8: dbit 1
0019 bseg_o9: dbit 1
dseg
0023 AddByte: ds 1 ; ideally, this should bump to 24h, as we've allocated more than 8bits
bseg ; back to BIT level
001A bseg_oA: dbit 1 ;does go back and fill in bseg bits..
It's not quite clever enough to auto-preserve a gap across booleans, for the next ds byte, but 8051 users typically code dseg clear of the boolean fields, as in the 8051 this is just a small subset of the memory map.
P2 is this on steroids, and allows ANY register to be boolean field, so it is more likely to mix long/boolean allocates.
This manual workaround does work, at keeping differing sizes correctly bumped..
0019 bseg_o9: dbit 1
= 19 last_bit SET bseg_o9
dseg at 20H+((last_bit OR 0x7)+1)/8 ;Manually round UP to next Free Byte
0024 AddByte: ds 1 ; now bumps to 24h
bseg ; back to BIT level
001A bseg_oA: dbit 1 ; back-fills with no ORG
This flow back-fills free booleans, if someone did want to avoid that, because they were also operating on whole longs, they can add packers.
If C and Z and NC and NZ cannot be reserved words, could NCF and NZF be used instead of !CF and !ZF? This would avoid an annoying key shift and besides it's if_nc_ and if_nz_ and djnz, not if_!c_ and if_!z_ and dj!z.
We can use "." instead of "\". I like "." better, too, but I was worried about the parser seeing something like 100.100 (being register 100). I think it ignores "." for PASM.
Check this out. This is all the Verilog it took to realize all the register.bit/flag instructions:
We can use "." instead of "\". I like "." better, too, but I was worried about the parser seeing something like 100.100 (being register 100). I think it ignores "." for PASM..
If C and Z and NC and NZ cannot be reserved words, could NCF and NZF be used instead of !CF and !ZF? This would avoid an annoying key shift and besides it's if_nc_ and if_nz_ and djnz, not if_!c_ and if_!z_ and dj!z.
A problem with that, is there is also !BitName to support. The NOT operator is not just not-zero or not-carry.
I'd be fine with
MOVB BitName, NOT C
MOVB C, NOT BitName
as an alias to
MOVB BitName, !C
MOVB C, !BitName
The NOT-BIT case is used rather infrequently in most code, so does not need to be super compact. C,Z are much more commonly used.
If C and Z and NC and NZ cannot be reserved words, could NCF and NZF be used instead of !CF and !ZF? This would avoid an annoying key shift and besides it's if_nc_ and if_nz_ and djnz, not if_!c_ and if_!z_ and dj!z.
A problem with that, is there is also !BitName to support. The NOT operator is not just not-zero or not-carry.
I'd be fine with
MOVB BitName, NOT C
MOVB C, NOT BitName
as an alias to
MOVB BitName, !C
MOVB C, !BitName
The NOT-BIT case is used rather infrequently in most code, so does not need to be super compact. C,Z are much more commonly used.
Must use CF if C not reserved. NOT CF instead of NCF would be plain silly, thus:
The big problem is that a source operand may be NOT'd. Spelling out NOT is kind of ugly, and "!" isn't much better. The destination operand cannot be NOT'd.
We could handle this like AND/ANDN and TEST/TESTN, where the N signifies that the source operand is NOT'd. Then, we have no need for NOT/! and we can get by with CF, ZF, and REG.{#}BIT:
We could handle this like AND/ANDN and TEST/TESTN, where the N signifies that the source operand is NOT'd. Then, we have no need for NOT/! and we can get by with CF, ZF, and REG.{#}BIT:
yeah, I played with that, but the problem here is which boolean does the NOT apply to, and when is the NOT applied ?
ie it could mean any of these...
CF = NOT(BitVar AND CF)
or
CF = BitVar AND NOT CF
or
CF = (NOT BitVar) AND CF
A trip to the manual is required each time..
The big problem is that a source operand may be NOT'd. Spelling out NOT is kind of ugly, and "!" isn't much better. The destination operand cannot be NOT'd.
I don't mind NOT, as it is common in HLL's, and your eye scans it quickly.
Support a choice of either ! or NOT symbols should keep those who hate typing, and like glyphs happy, and NOT for those more used to reading English...?
There is also NC as natural alias of NOT C, !C (& NZ) as was suggested above, which makes NOT, ! really apply only to BitVar inversion.. ie pushing to rarer cases.
Someone should be allowed to use NOT C, even if NC is allowed.
Notice
* The compiler tolerates both ! and ~ forms here
* The code uses the BIT operators in all cases, including
* NOT bit is managed with a char prefix, on the source char, in ASM.
The / is intel's choice (decades ago), I would have chosen ! or ~ in 2017
A lot has been added. Hope this isn't the last straw !?!?
Chip said this "Because the logic here mainly deals with one bit, instead of 32, the resource usage is very low. Maybe only two LE's more than before."
so it seems a lot of flexibility came, at very low cost.
There seems to be some overlap now, with OUTxx, DIRxx opcodes and new.improved MOVB/SETB/CLRB/NOTB as they can have OUT and DIR as destinations ?
(tho the former also update C,Z with INA, that seems a rare use ? )
Comments
Wow... really, Wahoo !!!!!
I was worried these may carry a cost...
This change will free a lot of COG memory, which is the most constrained resource in P2.
It also makes PLC type control operations easier to code, and smaller and faster...
That reads like it could be an operation, but I can understand multiple commas is less than ideal.
If you want a separator, why not just use the existing convention, which is a decimal point ?
(This also follows HLL conventions for record extraction)
ie Register.BitNumber is the common way this detail is managed on 8051 & others, and usually Boolean Vars are declared
like this and then that clear single boolean name is used, as in so there is usually no separator visible in the code, but this is also legal in P2
The existing convention out there, is a decimal point separator, easiest to just use that.
I'm fine with the simple C and Z, as they are going to be used a lot, and I recall a Prof, who marked down anyone who used single-variable letters as names....
Also note, the form is not just not-carry, but not-bit is allowed too, which requires some 'not prefix'.
!CF is also fine, tho if I were writing the assembler, I'd also include the likely candidates of ~BitName and NOT Bitname
NOT will likely already be supported in boolean expression evaluation in HLL
Yes, The fact that these are bit operations is more important and relevant
I think the decimal convention should be followed here; it's common practice elsewhere and there's no chance of it being confused for a float operation.
For the toolset, it might be worth considering a simple method of packing multiple bit variables into a single long without the programmer making the bit allocations directly.
Seems that can "pack multiple bit variables into a multiple bytes single long without the programmer making the bit allocations directly".
Pushing it further with this more complex test .... It's not quite clever enough to auto-preserve a gap across booleans, for the next ds byte, but 8051 users typically code dseg clear of the boolean fields, as in the 8051 this is just a small subset of the memory map.
P2 is this on steroids, and allows ANY register to be boolean field, so it is more likely to mix long/boolean allocates.
This manual workaround does work, at keeping differing sizes correctly bumped..
This flow back-fills free booleans, if someone did want to avoid that, because they were also operating on whole longs, they can add packers.
If C and Z and NC and NZ cannot be reserved words, could NCF and NZF be used instead of !CF and !ZF? This would avoid an annoying key shift and besides it's if_nc_ and if_nz_ and djnz, not if_!c_ and if_!z_ and dj!z.
Nobody's mentioned the unused instruction:
The option of last-resort:
Check this out. This is all the Verilog it took to realize all the register.bit/flag instructions:
Because the logic here mainly deals with one bit, instead of 32, the resource usage is very low. Maybe only two LE's more than before.
Wow
Easier to code than it is to explain, and compact as a bonus ! Whodathunk...?
I'd be fine with
MOVB BitName, NOT C
MOVB C, NOT BitName
as an alias to
MOVB BitName, !C
MOVB C, !BitName
The NOT-BIT case is used rather infrequently in most code, so does not need to be super compact. C,Z are much more commonly used.
Must use CF if C not reserved. NOT CF instead of NCF would be plain silly, thus:
MOVB BitName, NCF
MOVB CF, NOT BitName
although
MOVB BitName, NC
MOVB C, NOT BitName
looks so much nicer. And no !'s.
A few questions:
Isn't it either CF or ZF but never both together?
How do CLRB/SETB/NOTB/RNDB affect C? (They can't affect Z.)
Is RNDB a random bit?
All the above is valid code
They can affect Z, when Z is a destination
Boolean OPs are atomic, they have no effect on C, unless C is the explicit destination.
AFAIK, yes.
Those are unmistakable.
I kind of like the "!", though:
No, that's not great, either.
The big problem is that a source operand may be NOT'd. Spelling out NOT is kind of ugly, and "!" isn't much better. The destination operand cannot be NOT'd.
We could handle this like AND/ANDN and TEST/TESTN, where the N signifies that the source operand is NOT'd. Then, we have no need for NOT/! and we can get by with CF, ZF, and REG.{#}BIT:
How would that be?
Or, using big names:
It keeps the syntax sane.
yeah, I played with that, but the problem here is which boolean does the NOT apply to, and when is the NOT applied ?
ie it could mean any of these...
CF = NOT(BitVar AND CF)
or
CF = BitVar AND NOT CF
or
CF = (NOT BitVar) AND CF
A trip to the manual is required each time..
Yes, true, but they are also quite long...
To me, long names 'say' user-generated, and very short ones like C and Z 'say' system reserved.
I guess users can always do something like this to alias the names....
C BIT CFLAG
Z BIT ZFLAG
this should be legal in the tools... ?
I don't mind NOT, as it is common in HLL's, and your eye scans it quickly.
Support a choice of either ! or NOT symbols should keep those who hate typing, and like glyphs happy, and NOT for those more used to reading English...?
There is also NC as natural alias of NOT C, !C (& NZ) as was suggested above, which makes NOT, ! really apply only to BitVar inversion.. ie pushing to rarer cases.
Someone should be allowed to use NOT C, even if NC is allowed.
! ties in with SPIN too.
The TEST/TESTN instructions vary by an internally-NOT'd S. Same with AND/ANDN. Do you think those are reasonable?
It reads literally as AND BIT NOT DestBit, SourceBit, so is actually quite confusing
yup, and given they are one thing basically, it's important we keep perspective on that.
I totally vote for "!" being NOT. It's not like people are gonna type that a bazillion times.
To me they are sub-optimal, as the detail of which operand is inverted, & when, is not visible from simply reading the source.
The benefit of the clear and explicit !,NOT is anyone can read code, and know what is being applied when.
Programmers coming from FreeBASIC & variants, all the Wirth Languages, and PLC IEC 61131 will be used to scanning NOT in their source code.
I don't mind CF & ZF or C & Z for that matter or NC & NZ either.
If it's MOVBN, ANDBN etc MOVNB, ANDNB, etc makes more sense to me.
But its not that important now. The instructions are there which is the main part.
A lot has been added. Hope this isn't the last straw !?!?
(added P2 syntax columns)
Notice
* The compiler tolerates both ! and ~ forms here
* The code uses the BIT operators in all cases, including
* NOT bit is managed with a char prefix, on the source char, in ASM.
The / is intel's choice (decades ago), I would have chosen ! or ~ in 2017
Chip said this
"Because the logic here mainly deals with one bit, instead of 32, the resource usage is very low. Maybe only two LE's more than before."
so it seems a lot of flexibility came, at very low cost.
There seems to be some overlap now, with OUTxx, DIRxx opcodes and new.improved MOVB/SETB/CLRB/NOTB as they can have OUT and DIR as destinations ?
(tho the former also update C,Z with INA, that seems a rare use ? )