The only thing I'm a little nervous about with changing the BITx instructions so that they can no longer read the previous instruction's state is that we may be losing some useful functionality. An atomic "set bit and test previous value" can be useful for semaphores around interrupts and such. Will it get used a lot? Probably not, but then these particular bit operations may not be much either.
Let's look at what we can do now (v18) in one instruction:
testb $, #18 wc ' C := 1, immediate bit is always set
testb $, #23 wc ' C := 0, assuming the encoding of testb does not change
testb X, Y wc ' C := X.Y
if_c testb X,Y wc ' C := C AND X.Y
if_nc testb X,Y wc ' C := C OR X.Y
What's not so convenient are C := !C (it can sometimes be faked by using Z as a proxy for !C, as we saw above) and C := Z. I think the MODCZ instruction can handle both of those, as well as most operations between C and Z, so it seems like with that we'll be in pretty good shape.
It would always compute the logical function for both C and Z, then write each as directed by WC/WZ. This gets redundancy out of the syntax. Also, it allows the operand to be just D,{#}S.
It would always compute the logical function for both C and Z, then write each as directed by WC/WZ. This gets redundancy out of the syntax. Also, it allows the operand to be just D,{#}S.
So you mean the legal operands suffix are {WC} , {WZ}, {WC,WZ}, but {} is illegal ? (what actually happens?)
That would mean this opcode can do this, right ?
EEEE 0100001 CZI DDDDDDDDD SSSSSSSSS ANDFN D,S/# {WC,WZ}
C = Bitname AND !C
Z = Bitname AND !Z
(and both of the above, should anyone need that ... )
but not
Bitname = Bitname AND !C
Bitname = Bitname AND !Z
Addit: Ah, I see from the grouping above, the {} case is borrowed for another opcode. That's one question sorted.
BITANDN {} -> BITH
Ah, actually we *can* already do NOT (and XOR) in one instruction. It does require a scratch register to be set to a known value:
one long 1
' set C := !C
cmpx one, #1 wc ' if C = 0, one < 1+C is true, so C := 1
' if C = 1, one < 1+C is false, so C := 0
Having that predefined register around also makes the C:=1 and C:=0 cases much clearer.
So maybe everything we need is already in v18.
I still like the MODCZ instruction, it could be very handy.
I don't like the idea of changing the way the wc,wz flags work for the BIT instructions. It's not orthogonal, and it gets rid of potentially useful functionality. Besides, a lot of those "new" instructions are redundant, e.g. BITAND X,Y wc is:
Let's look at what we can do now (v18) in one instruction:
testb $, #18 wc ' C := 1, immediate bit is always set
testb $, #23 wc ' C := 0, assuming the encoding of testb does not change
testb X, Y wc ' C := X.Y
if_c testb X,Y wc ' C := C AND X.Y
if_nc testb X,Y wc ' C := C OR X.Y
one long 1
' set C := !C
cmpx one, #1 wc ' if C = 0, one < 1+C is true, so C := 1
' if C = 1, one < 1+C is false, so C := 0
All these examples are clever gymnastics, but rather illustrate the problem.
How would a first year student decode any of these ?
Ideally, source code should be 'read at a glance' stuff, and easy to maintain.
I think my favorite is this one, for CLR C
testb $, #23 wc ' C := 0, assuming the encoding of testb does not change
The full bit instructions did deliver 'read at a glance', all these 'hey, look what we can do' gymnastics, just prove what has been lost.
All these examples are clever gymnastics, but rather illustrate the problem.
How would a first year student decode any of these ?
Ideally, source code should be 'read at a glance' stuff, and easy to maintain.
Which is why we'd want to use macros for these, or even add them as instructions in PASM, or put them in a compiler. All of the details can be hidden. The architecture is capable of a vast amount of things that we haven't even scratched the surface of. Unfortunately, until we get silicon it is all moot .
It looks like we can do all kinds of logical operations on register bits with conditionals, but the ability to accumulate logical results, as you go, into C and Z is very limited. Do you agree?
All we would miss by having WC/WZ change the BITxxx bit writes into flag writes would be that the bit writes would not report back the prior state of the bit. However, if both WC and WZ are expressed for a bit-write instruction, we could have the prior state written back to C and NZ. Would that give you much indigestion?
All we would miss by having WC/WZ change the BITxxx bit writes into flag writes would be that the bit writes would not report back the prior state of the bit. However, if both WC and WZ are expressed for a bit-write instruction, we could have the prior state written back to C and NZ. Would that give you much indigestion?
Does TESTB still exist ? That lets you read a Bool State into C,NZ ? So covers that rather rare case with one more line.
Does this new scheme still lose the group of
Bitname = Bitname AND !C
Bitname = Bitname AND !Z
that were available in full bit instructions ?
All we would miss by having WC/WZ change the BITxxx bit writes into flag writes would be that the bit writes would not report back the prior state of the bit. However, if both WC and WZ are expressed for a bit-write instruction, we could have the prior state written back to C and NZ. Would that give you much indigestion?
Does TESTB still exist ? That lets you read a Bool State into C,NZ ? So covers that rather rare case with one more line.
Does this new scheme still lose the group of
Bitname = Bitname AND !C
Bitname = Bitname AND !Z
that were available in full bit instructions ?
The "Bitname = Bitname AND !C" type stuff is gone. However, those can be more than recreated through conditionals:
All we would miss by having WC/WZ change the BITxxx bit writes into flag writes would be that the bit writes would not report back the prior state of the bit. However, if both WC and WZ are expressed for a bit-write instruction, we could have the prior state written back to C and NZ. Would that give you much indigestion?
I guess there are other ways to do atomic read/modify, as long as MUXC and the other logical operations can still report back the previous bit state. So it's not a deal breaker. Personally I find the new use of wc,wz a bit weird, but maybe I just haven't wrapped my head around it. It also seems like we're adding a lot of new instructions / special cases for a feature that conceptually seems like it shouldn't need that many.
If we had a TESTNB instruction maybe we could achieve the logical operations with conditionals the way you indicated above? I'm not sure. It seems like it's the NOT case that's the awkward one.
All we would miss by having WC/WZ change the BITxxx bit writes into flag writes would be that the bit writes would not report back the prior state of the bit. However, if both WC and WZ are expressed for a bit-write instruction, we could have the prior state written back to C and NZ. Would that give you much indigestion?
Does TESTB still exist ? That lets you read a Bool State into C,NZ ? So covers that rather rare case with one more line.
Does this new scheme still lose the group of
Bitname = Bitname AND !C
Bitname = Bitname AND !Z
that were available in full bit instructions ?
The "Bitname = Bitname AND !C" type stuff is gone. However, those can be more than recreated through conditionals:
These new BITx instructions are a lot of mnemonics, but very little logic.
I thought, too, that TESTNB would probably solve most of the problem. It's easy to accumulate ANDs and ORs with complementary reads, but XOR is maybe still difficult.
..
This encoding can be used for not just BITx, but the other four pin-related DIRx/OUTx/FLTx/DRVx instruction blocks:
..
Imagine the same thing with BITx done to all of those other four blocks.
I fear I'll imagine up the wrong operation.
I can see OUTxx for example has a Boolean destination, which is one of 64 port pins.
With the BITOP Logical group, rules look to be {} changes the opcode, and WC or WZ writes to only C or Z.
Not quite sure how to apply those new rules, to an output pin ?
These INx instructions let you read the INA/INB bits and do logic ops into the flags. The DIRx/OUTx/FLTx/DRVx instructions affect the DIRA/DIRB/OUTA/OUTB bits, but not the flags.
Here is the new pin operations instruction block:
...
These INx instructions let you read the INA/INB bits and do logic ops into the flags. The DIRx/OUTx/FLTx/DRVx instructions affect the DIRA/DIRB/OUTA/OUTB bits, but not the flags.
I do not know how the opcodes have to be optimized and waht is behind the production of a good working set.
But after all this discussions, and with some inspiration from other environments, I would love it to be possible to have all this in the effect field like (taken from prior post):
HeaterPin := (MinTemp < Temp < MaxTemp) AND HeaterON AND NOT ThermalTrip OR TestPin
could be realized as:
CMP Temp,MaxTemp WC
CMP MinTemp,Temp AC
BIT Flags,#HeaterOn AC
BITN Flags,#ThermalTrip AC
BIT Flags,#TestPin OC
DRVC #HeaterPin
where
WC sets C from instruction
AC ands prior C with instruction C
OC ors C with instructin C
XC xors C with instruction C
conditionals works the same way of course
Comments
Let's look at what we can do now (v18) in one instruction: What's not so convenient are C := !C (it can sometimes be faked by using Z as a proxy for !C, as we saw above) and C := Z. I think the MODCZ instruction can handle both of those, as well as most operations between C and Z, so it seems like with that we'll be in pretty good shape.
It would always compute the logical function for both C and Z, then write each as directed by WC/WZ. This gets redundancy out of the syntax. Also, it allows the operand to be just D,{#}S.
That would mean this opcode can do this, right ?
Addit: Ah, I see from the grouping above, the {} case is borrowed for another opcode. That's one question sorted.
BITANDN {} -> BITH
So maybe everything we need is already in v18.
I still like the MODCZ instruction, it could be very handy.
I don't like the idea of changing the way the wc,wz flags work for the BIT instructions. It's not orthogonal, and it gets rid of potentially useful functionality. Besides, a lot of those "new" instructions are redundant, e.g. BITAND X,Y wc is:
How would a first year student decode any of these ?
Ideally, source code should be 'read at a glance' stuff, and easy to maintain.
I think my favorite is this one, for CLR C
The full bit instructions did deliver 'read at a glance', all these 'hey, look what we can do' gymnastics, just prove what has been lost.
It looks like we can do all kinds of logical operations on register bits with conditionals, but the ability to accumulate logical results, as you go, into C and Z is very limited. Do you agree?
All we would miss by having WC/WZ change the BITxxx bit writes into flag writes would be that the bit writes would not report back the prior state of the bit. However, if both WC and WZ are expressed for a bit-write instruction, we could have the prior state written back to C and NZ. Would that give you much indigestion?
Does this new scheme still lose the group of
Bitname = Bitname AND !C
Bitname = Bitname AND !Z
that were available in full bit instructions ?
The "Bitname = Bitname AND !C" type stuff is gone. However, those can be more than recreated through conditionals:
Ah, ok, - I guess I can quote Eric here...
I guess there are other ways to do atomic read/modify, as long as MUXC and the other logical operations can still report back the previous bit state. So it's not a deal breaker. Personally I find the new use of wc,wz a bit weird, but maybe I just haven't wrapped my head around it. It also seems like we're adding a lot of new instructions / special cases for a feature that conceptually seems like it shouldn't need that many.
If we had a TESTNB instruction maybe we could achieve the logical operations with conditionals the way you indicated above? I'm not sure. It seems like it's the NOT case that's the awkward one.
Also
Nothing for XOR or !bit, though...
I think the new BITGET can do atomic, one bit, non destructive read ?
I thought, too, that TESTNB would probably solve most of the problem. It's easy to accumulate ANDs and ORs with complementary reads, but XOR is maybe still difficult.
That's correct. No need for TESTB/TESTBN, anymore.
Okay. I'm obviously still behind on the changes. Does this mean we now have:
If I implement this stuff, which would take about an hour, we'll have these:
Imagine the same thing with BITx done to all of those other four blocks. Hey, were you going to point out that would be 40 new mnemonics?
I can see OUTxx for example has a Boolean destination, which is one of 64 port pins.
With the BITOP Logical group, rules look to be {} changes the opcode, and WC or WZ writes to only C or Z.
Not quite sure how to apply those new rules, to an output pin ?
Here is the new BITx instruction block:
Here is the new pin operations instruction block:
These INx instructions let you read the INA/INB bits and do logic ops into the flags. The DIRx/OUTx/FLTx/DRVx instructions affect the DIRA/DIRB/OUTA/OUTB bits, but not the flags.
A few questions:
Is the assembler going to enforce the requirement/restriction of WC/WZ based on mnemonic?
Are BITAND, etc. updating D or the flag(s)? If it's the flags, maybe use "CZ" prefix instead of "BIT"?
I see BITEST/BITESTN instead of BITGET/BITGETN. Is that correct?
What is BITRND?
I do not know how the opcodes have to be optimized and waht is behind the production of a good working set.
But after all this discussions, and with some inspiration from other environments, I would love it to be possible to have all this in the effect field like (taken from prior post):
where
WC sets C from instruction
AC ands prior C with instruction C
OC ors C with instructin C
XC xors C with instruction C
conditionals works the same way of course