SFUNC question

13468913

Comments

  • I got rid of BOTONE and renamed TOPONE to ENCOD. That got rid of a 32-bit mux and other LE's. It's now compiling 6% smaller, overall, which I don't understand. I'll know soon, though, why.
  • jmgjmg Posts: 14,540
    cgracey wrote: »
    That overlap is superficial, since the OUTx/DIRx instructions automatically index between port A and B. In other words, you only need the pin number.
    Yes, I can see the OUT,DIR have a 'reach' of 64 bits but if you give the same pre defined PinName to MOVB/SETB/CLRB/NOTB, the same outcome can result.

    I can see if you use a REG, as a bit pointer, OUT can scan all pins on the device in one opcode, whilst _B opcodes have a reach of 32, so can manage a port only, in one opcode.
    How often is wanting to pointer-index over 64 pins actually required ?

  • cgraceycgracey Posts: 13,125
    edited 2017-05-02 - 05:06:07
    That kind of indexing occurs in an object when a pin number is specified by the parent.
  • jmg wrote: »
    TonyB wrote: »
    cgracey wrote: »
    I forgot to mention that there are other intra-flag operations like:
    XORB    CF,!ZF
    ANDB    ZF,CF
    NOTB    CF
    

    A few questions:

    Isn't it either CF or ZF but never both together?
    What do you mean 'never both together' ?
    All the above is valid code
    TonyB wrote: »
    How do CLRB/SETB/NOTB/RNDB affect C? (They can't affect Z.)
    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.

    It seems to me there are more bit instruction permutations than available opcodes:
    EEEE 0110110 C0I DDDDDDDDD SSSSSSSSS        CLRB    D.{#}S      {WC}
    EEEE 0110110 C1I DDDDDDDDD SSSSSSSSS        SETB    D.{#}S      {WC}
    EEEE 0110111 C0I DDDDDDDDD SSSSSSSSS        NOTB    D.{#}S      {WC}
    EEEE 0110111 C1I DDDDDDDDD SSSSSSSSS        RNDB    D.{#}S      {WC}
    
    EEEE 0111000 00I DDDDDDDDD SSSSSSSSS        MOVB    D.{#}S,CF
    EEEE 0111000 01I DDDDDDDDD SSSSSSSSS        MOVBN   D.{#}S,CF
    EEEE 0111000 10I DDDDDDDDD SSSSSSSSS        MOVB    D.{#}S,ZF
    EEEE 0111000 11I DDDDDDDDD SSSSSSSSS        MOVBN   D.{#}S,ZF
    EEEE 0111001 00I DDDDDDDDD SSSSSSSSS        MOVB    CF,D.{#}S
    EEEE 0111001 01I DDDDDDDDD SSSSSSSSS        MOVBN   CF,D.{#}S
    EEEE 0111001 10I DDDDDDDDD SSSSSSSSS        MOVB    ZF,D.{#}S
    EEEE 0111001 11I DDDDDDDDD SSSSSSSSS        MOVBN   ZF,D.{#}S
    
    EEEE 0111010 00I DDDDDDDDD SSSSSSSSS        ANDB    D.{#}S,CF
    EEEE 0111010 01I DDDDDDDDD SSSSSSSSS        ANDBN   D.{#}S,CF
    EEEE 0111010 10I DDDDDDDDD SSSSSSSSS        ANDB    D.{#}S,ZF
    EEEE 0111010 11I DDDDDDDDD SSSSSSSSS        ANDBN   D.{#}S,ZF
    EEEE 0111011 00I DDDDDDDDD SSSSSSSSS        ANDB    CF,D.{#}S
    EEEE 0111011 01I DDDDDDDDD SSSSSSSSS        ANDBN   CF,D.{#}S
    EEEE 0111011 10I DDDDDDDDD SSSSSSSSS        ANDB    ZF,D.{#}S
    EEEE 0111011 11I DDDDDDDDD SSSSSSSSS        ANDBN   ZF,D.{#}S
    
    EEEE 0111100 00I DDDDDDDDD SSSSSSSSS        ORB     D.{#}S,CF
    EEEE 0111100 01I DDDDDDDDD SSSSSSSSS        ORBN    D.{#}S,CF
    EEEE 0111100 10I DDDDDDDDD SSSSSSSSS        ORB     D.{#}S,ZF
    EEEE 0111100 11I DDDDDDDDD SSSSSSSSS        ORBN    D.{#}S,ZF
    EEEE 0111101 00I DDDDDDDDD SSSSSSSSS        ORB     CF,D.{#}S
    EEEE 0111101 01I DDDDDDDDD SSSSSSSSS        ORBN    CF,D.{#}S
    EEEE 0111101 10I DDDDDDDDD SSSSSSSSS        ORB     ZF,D.{#}S
    EEEE 0111101 11I DDDDDDDDD SSSSSSSSS        ORBN    ZF,D.{#}S
    
    EEEE 0111110 00I DDDDDDDDD SSSSSSSSS        XORB    D.{#}S,CF
    EEEE 0111110 01I DDDDDDDDD SSSSSSSSS        XORBN   D.{#}S,CF
    EEEE 0111110 10I DDDDDDDDD SSSSSSSSS        XORB    D.{#}S,ZF
    EEEE 0111110 11I DDDDDDDDD SSSSSSSSS        XORBN   D.{#}S,ZF
    EEEE 0111111 00I DDDDDDDDD SSSSSSSSS        XORB    CF,D.{#}S
    EEEE 0111111 01I DDDDDDDDD SSSSSSSSS        XORBN   CF,D.{#}S
    EEEE 0111111 10I DDDDDDDDD SSSSSSSSS        XORB    ZF,D.{#}S
    EEEE 0111111 11I DDDDDDDDD SSSSSSSSS        XORBN   ZF,D.{#}S
    

    What is the opcode for MOVB CF,ZF for example?
  • cgraceycgracey Posts: 13,125
    edited 2017-05-02 - 15:33:33
    Those pure CF/ZF opcodes will be in the block of unary functions where SPLITB/MERGEB/etc. are. It will take only 4 bits to cover every logic function for each flag. So, 8 bits of immediate D will handle it. I haven't gotten there yet, but will be there as soon as I get things up again. Right now, after making these changes, some error of mine is causing things not to work. This is typical when a big change is made.
  • cgraceycgracey Posts: 13,125
    edited 2017-05-02 - 15:50:02
    I've got the assembler all updated for the new "d.{#}s" and "!" syntax. I feel funny about how it makes the source code look, as far as knowing that a flag has been modified.

    The BITx instructions with "WC" or "WZ" after them were very easy on the eyes, as there was simplicity and visibility for flag effects. This new way, while much more flexible, requires that you slow way down, in order to tell if a flag has been affected. I almost want to require WC/WF where flag writes are occurring. That way, you'd be able to see, at a glance, where flags are being modified.
  • This new way, while much more flexible, requires that you slow way down, in order to tell if a flag has been affected. I almost want to require WC/WF where flag writes are occurring.

    :/
  • jmgjmg Posts: 14,540
    cgracey wrote: »
    I've got the assembler all updated for the new "d.{#}s" and "!" syntax.
    Sounds cool.
    Can you also declare a NamedBoolean, and use that name ?
    Along the lines of
    BooleanName     BIT   Dreg.#12    ; Bit12 in D reg
    BooleanNameI    BIT   Dreg.Sreg   ; Reg-pair Boolean Indirect Pointer
    
        SETB    BooleanName
        CLRB    BooleanNameI
        ORB     C,BooleanName
        ANDB    Z,!BooleanNameI
        XORB    BooleanName,C
    
    
    cgracey wrote: »
    I feel funny about how it makes the source code look, as far as knowing that a flag has been modified.

    The BITx instructions with "WC" or "WZ" after them were very easy on the eyes, as there was simplicity and visibility for flag effects. This new way, while much more flexible, requires that you slow way down, in order to tell if a flag has been affected.

    That's one of the reasons I favour using the simple and clear C,Z as that makes it very clear 'as far as knowing that a flag has been modified.'
    CF,ZF requires users know that CF really means C, and ZF really means Z & not as easy on the eyes

    When you use named booleans, the code is further easier to scan - anything with a C or Z Destination in it, modifies Z or C
  • cgracey wrote: »
    jmg wrote: »
    cgracey wrote: »
    jmg wrote: »
    Can the smart pins capture from a 3rd pin, when Quad counting from 2 others ?

    No. The quadrature encoder can work either periodically, reporting the count delta every X clocks, or work in totalizer mode. In its current design, you would have to either watch for the 'zero' pin or use it to generate an interrupt. It would be easy to reset the counter in totalizer mode when 'zero' went high. It seems like this would be troublesome in cases of bidirectional rotation because of hysteresis on the 'zero' detector.
    That's probably tolerable, as interrupt can be quite quick, in machine terms.
    Most Z designs I've seen have deliberately narrow Z, so it 'fits inside' a single state, and so 'hysteresis' on direction change is not an issue.

    I just looked at the smart pin and each mode is limited to two inputs and one output. For PWM in SMPS mode, it can output PWM and simultaneously monitor I and V digital inputs. For quadrature modes, there's no output, but the two inputs get used as A and B.

    Chip,
    Z is a third channel and is used to reset the counter (totalizer).

    You have to distinguish between device and counter module.
    -The device eg encoder usually output 90° out of phase pulses on A and B while outputs a single pulse per revolution (same length as A/B) on Z. Here there is no hysteresis issue, the 3 channels are always in sync. If you use your own sensor (eg mechanical switch or proximity sensor) for z signal then you have to manage hysteresis and/or direction issues.
    -The counter module updates a totalizer based on pulses of channels A and B and resets it with rising or falling edge on Z channel. Z channel usually have also software enable and a preset value. At Z pulse the counter/totalizer becomes equal to the preset value. The counter module usually, beside updating the totalizer (which gives you position usually), calculates also frequency in 2 modes: counting A/B pulses in given time or counting internal reference frequency pulses in one A/B period. The former is better for high speeds while the latter gives you better resolution at low speeds.
    So usually from an industrial counter module you have both position and speed.

    Regarding edges evaluation:
    - you can for example count pulses on A channel while B gives you the direction.
    - you can evaluate rising and falling edge on A and B together with stable state on the opposite channel and thus increasing by 4x the quadrature resolution.
    How is the smart pins working: on pulse/direction or edges of A/B?
  • jmgjmg Posts: 14,540
    This probably needs a separate thread..
    dMajo wrote: »
    Regarding edges evaluation:
    - you can for example count pulses on A channel while B gives you the direction.
    - you can evaluate rising and falling edge on A and B together with stable state on the opposite channel and thus increasing by 4x the quadrature resolution.
    How is the smart pins working: on pulse/direction or edges of A/B?
    The Quad mode uses every edge, so is a true Quad Counter.

    Not sure about support of a DIRN and COUNT mode, some systems do generate that.
    The smart pins certainly can do UP/DOWN, and I see inc on A-rise, dec on B-rise but do not see DIRN & COUNT mode ?
    Maybe that was missed ?

    DOCs have this
    %MMMMM:	00000   = smart pin off (default)
    00001   = long repository              (P[12:10] != %101)
    00010   = long repository              (P[12:10] != %101)
    00011   = long repository              (P[12:10] != %101)
    00001   = DAC noise                    (P[12:10]  = %101)
    00010   = DAC 16-bit dither, noise     (P[12:10]  = %101)
    00011   = DAC 16-bit dither, PWM       (P[12:10]  = %101)
    00100*  = pulse/cycle output
    00101*  = transition output
    00110*  = NCO frequency
    00111*  = NCO duty
    01000*  = PWM triangle
    01001*  = PWM sawtooth
    01010*  = PWM switch-mode power supply, V and I feedback
    01011   = periodic/continuous, A-B quadrature encoder
    01100   = periodic/continuous, inc on A-high
    01101   = periodic/continuous, inc on A-rise
    01110   = periodic/continuous, inc on A-high, dec on B-high
    01111   = periodic/continuous, inc on A-rise, dec on B-rise
    10000   = time A states
    10001   = time A-high states
    10010   = time X A-highs
    10011   = for X periods, count time
    10100   = for X periods, count states
    10101   = for periods in X+ clocks, count time
    10110   = for periods in X+ clocks, count states
    10111   = for periods in X+ clocks, count periods
    11000*  = USB host, low-speed          (even/odd pin pair = DM/DP)
    11001*  = USB host, high-speed         (even/odd pin pair = DM/DP)
    11010*  = USB device, low-speed        (even/odd pin pair = DM/DP)
    11011*  = USB device, high-speed       (even/odd pin pair = DM/DP)
    11100*  = sync serial transmit         (A-data, B-clock)
    11101   = sync serial receive          (A-data, B-clock)
    11110*  = async serial transmit        (baudrate)
    11111   = async serial receive         (baudrate)
    
  • I'm not at home to look things up, but I believe the inputs can be preset to 1/0 level I think. So, mode 01110 can do the job of mode 01100, and mode 01111 can do the job of 01101. That would free up a couple of modes.

    One mode can then be "periodic/continuous, inc on A-rise (B-low), dec on A-rise (B-high)"
  • There is no need for every conceivable instruction!
    It's nice to have a special instruction for a commonly used set of instructions. However, obscure instruction groups don't need to waste valuable silicon and power.

    A couple of years ago I raised the possibility of a generic helper instruction for calculating various CRCC algorithms. However I would rather see silicon.
  • cgracey wrote: »
    Cluso99,

    I've got those RCZR and RCZL opcodes already implemented, but it would be easy to change which bits do what.

    Here is part of the Verilog that does the job. Note the first two bits of each "u" term are the new C/Z states:
    wire [31:0] rczr	=	{c, z, d[31:2]};
    wire [31:0] rczl	=	{d[29:0], c, z};
    ...
    
    wire [15:0][33:0] u = { 2'b0,		wrnz,
    ...
    			d[31:30],	rczl,
    			d[1:0],		rczr,
    ...
    
    Sorry to take so long to answer these

    Here is what I meant for rotating just using the free bits after a CALL has saved the return address & c/z flags.
    wire [31:0] rczr	=	{c, z, d[31:22], d[19:0]};
    wire [31:0] rczl	=	{d[29:20], c, z, d[19:0]};
    ...
    
    wire [15:0][33:0] u = { 2'b0,		wrnz,
    ...
    			d[31:30],	rczl,
    			d[1:0],		rczr,
    ...
    
    I am presuming that "u[33:32]" gets tested with WC & WZ to determine whether C & Z bits get updated.

    ie elsewhere this is performed
    C = wc ? u[33] : c;
    Z = wz ? u[32] : z;
    

    Chip, will this do for spin2 too, where you save & restore C & Z ???
  • Cluso99 wrote: »
    ...However I would rather see silicon.

    Exactly.

    @cgracey, as long as there is no silicon, people will continue suggesting changes. And as long as you keep implementing those suggestions, there will be no silicon.
  • Cluso's far from innocent here. :P
  • evanhevanh Posts: 10,088
    edited 2017-05-03 - 13:33:16
    evanh wrote: »
    I'm not at home to look things up, but I believe the inputs can be preset to 1/0 level I think. So, mode 01110 can do the job of mode 01100, and mode 01111 can do the job of 01101. That would free up a couple of modes.

    One mode can then be "periodic/continuous, inc on A-rise (B-low), dec on A-rise (B-high)"
    I got that wrong. There is no 1/0 level selector for the smartpin inputs.
    D/# = %AAAA_BBBB_FFF_PPPPPPPPPPPPP_TT_MMMMM_0
    
    %BBBB:    ‘B’ input selector
              0xxx = true (default)
              1xxx = inverted
              x000 = this pin’s read state (default)
              x001 = relative +1 pin’s read state
              x010 = relative +2 pin’s read state
              x011 = relative +3 pin’s read state
              x100 = this pin’s OUT bit from cogs
              x101 = relative -3 pin’s read state
              x110 = relative -2 pin’s read state
              x111 = relative -1 pin’s read state
    
    It can be achieved through an extra step though - Set the above selector mode to 1100, and do an OUTH to that pin so that the forced high is treated as a steady low at the smartpin B input.
  • TonyBTonyB Posts: 73
    edited 2017-05-03 - 15:57:33
    cgracey wrote: »
    I've got the assembler all updated for the new "d.{#}s" and "!" syntax. I feel funny about how it makes the source code look, as far as knowing that a flag has been modified.

    The BITx instructions with "WC" or "WZ" after them were very easy on the eyes, as there was simplicity and visibility for flag effects. This new way, while much more flexible, requires that you slow way down, in order to tell if a flag has been affected. I almost want to require WC/WF where flag writes are occurring. That way, you'd be able to see, at a glance, where flags are being modified.

    The syntax has been broken. The new bit instruction mnemonics are simple but the operands are not as much as they could be, inconsistent CF & ZF have had to be contrived and WC & WZ have been lost. There must be a better way and I have come up with two options.

    Option 1
    Old				New
    
    CLRB	D.{#}S			CLRB	D.{#}S	{WC}	
    SETB	D.{#}S			SETB	D.{#}S	{WC}
    NOTB	D.{#}S			NOTB	D.{#}S	{WC}
    RNDB	D.{#}S			RNDB	D.{#}S	{WC}
    
    MOVB	D.{#}S,CF		MOVBC	D.{#}S
    MOVB	D.{#}S,!CF		MOVBNC	D.{#}S
    MOVB	D.{#}S,ZF		MOVBZ	D.{#}S
    MOVB	D.{#}S,!ZF		MOVBNZ	D.{#}S
    MOVB	CF,D.{#}S		MOVB	D.{#}S	WC
    MOVB	CF,!D.{#}S		MOVBN	D.{#}S	WC
    MOVB	ZF,D.{#}S		MOVB	D.{#}S	WZ
    MOVB	ZF,!D.{#}S		MOVBN	D.{#}S	WZ
    
    ANDB	D.{#}S,CF		ANDBC	D.{#}S
    ANDB	D.{#}S,!CF		ANDBNC	D.{#}S
    ANDB	D.{#}S,ZF		ANDBZ	D.{#}S
    ANDB	D.{#}S,!ZF		ANDBNZ	D.{#}S
    ANDB	CF,D.{#}S		ANDB	D.{#}S	WC
    ANDB	CF,!D.{#}S		ANDBN	D.{#}S	WC
    ANDB	ZF,D.{#}S		ANDB	D.{#}S	WZ
    ANDB	ZF,!D.{#}S		ANDBN	D.{#}S	WZ
    
    ORB	D.{#}S,CF		ORBC	D.{#}S
    ORB	D.{#}S,!CF		ORBNC	D.{#}S
    ORB	D.{#}S,ZF		ORBZ	D.{#}S
    ORB	D.{#}S,!ZF		ORBNZ	D.{#}S
    ORB	CF,D.{#}S		ORB	D.{#}S	WC
    ORB	CF,!D.{#}S		ORBN	D.{#}S	WC
    ORB	ZF,D.{#}S		ORB	D.{#}S	WZ
    ORB	ZF,!D.{#}S		ORBN	D.{#}S	WZ
    
    XORB	D.{#}S,CF		XORBC	D.{#}S
    XORB	D.{#}S,!CF		XORBNC	D.{#}S
    XORB	D.{#}S,ZF		XORBZ	D.{#}S
    XORB	D.{#}S,!ZF		XORBNZ	D.{#}S
    XORB	CF,D.{#}S		XORB	D.{#}S	WC
    XORB	CF,!D.{#}S		XORBN	D.{#}S	WC
    XORB	ZF,D.{#}S		XORB	D.{#}S	WZ
    XORB	ZF,!D.{#}S		XORBN	D.{#}S	WZ
    
    CLRB	CF			CLRB		WC
    CLRB	ZF			CLRB		WZ
    				CLRB		WC WZ
    
    SETB	CF			SETB		WC
    SETB	ZF			SETB		WZ
    				SETB		WC WZ
    
    NOTB	CF			NOTB		WC
    NOTB	ZF			NOTB		WZ
    				NOTB		WC WZ
    
    MOVB	CF,ZF			MOVBZ		WC
    MOVB	CF,!ZF			MOVBNZ		WC
    MOVB	ZF,CF			MOVBC		WZ
    MOVB	ZF,!CF			MOVBNC		WZ
    
    ANDB	CF,ZF			ANDBZ		WC
    ANDB	CF,!ZF			ANDBNZ		WC
    ANDB	ZF,CF			ANDBC		WZ
    ANDB	ZF,!CF			ANDBNC		WZ
    
    ORB	CF,ZF			ORBZ		WC
    ORB	CF,!ZF			ORBNZ		WC
    ORB	ZF,CF			ORBC		WZ
    ORB	ZF,!CF			ORBNC		WZ
    
    XORB	CF,ZF			XORBZ		WC
    XORB	CF,!ZF			XORBNZ		WC
    XORB	ZF,CF			XORBC		WZ
    XORB	ZF,!CF			XORBNC		WZ
    

    Syntax fixed.

    CF & ZF & ! ditched and operands reduced from two to one or none. Still room for improvement, though. If the single operand contains "." or MOV/AND/OR/XOR/CLR/SET/NOT have no operand, then 1-bit operation is implicit and B can be eliminated.

    Option 2
    Old				New
    
    CLRB	D.{#}S			CLR	D.{#}S	{WC}	
    SETB	D.{#}S			SET	D.{#}S	{WC}
    NOTB	D.{#}S			NOT	D.{#}S	{WC}
    RNDB	D.{#}S			RND	D.{#}S	{WC}
    
    MOVB	D.{#}S,CF		MOVC	D.{#}S
    MOVB	D.{#}S,!CF		MOVNC	D.{#}S
    MOVB	D.{#}S,ZF		MOVZ	D.{#}S
    MOVB	D.{#}S,!ZF		MOVNZ	D.{#}S
    MOVB	CF,D.{#}S		MOV	D.{#}S	WC
    MOVB	CF,!D.{#}S		MOVN	D.{#}S	WC
    MOVB	ZF,D.{#}S		MOV	D.{#}S	WZ
    MOVB	ZF,!D.{#}S		MOVN	D.{#}S	WZ
    
    ANDB	D.{#}S,CF		ANDC	D.{#}S
    ANDB	D.{#}S,!CF		ANDNC	D.{#}S
    ANDB	D.{#}S,ZF		ANDZ	D.{#}S
    ANDB	D.{#}S,!ZF		ANDNZ	D.{#}S
    ANDB	CF,D.{#}S		AND	D.{#}S	WC
    ANDB	CF,!D.{#}S		ANDN	D.{#}S	WC
    ANDB	ZF,D.{#}S		AND	D.{#}S	WZ
    ANDB	ZF,!D.{#}S		ANDN	D.{#}S	WZ
    
    ORB	D.{#}S,CF		ORC	D.{#}S
    ORB	D.{#}S,!CF		ORNC	D.{#}S
    ORB	D.{#}S,ZF		ORZ	D.{#}S
    ORB	D.{#}S,!ZF		ORNZ	D.{#}S
    ORB	CF,D.{#}S		OR	D.{#}S	WC
    ORB	CF,!D.{#}S		ORN	D.{#}S	WC
    ORB	ZF,D.{#}S		OR	D.{#}S	WZ
    ORB	ZF,!D.{#}S		ORN	D.{#}S	WZ
    
    XORB	D.{#}S,CF		XORC	D.{#}S
    XORB	D.{#}S,!CF		XORNC	D.{#}S
    XORB	D.{#}S,ZF		XORZ	D.{#}S
    XORB	D.{#}S,!ZF		XORNZ	D.{#}S
    XORB	CF,D.{#}S		XOR	D.{#}S	WC
    XORB	CF,!D.{#}S		XORN	D.{#}S	WC
    XORB	ZF,D.{#}S		XOR	D.{#}S	WZ
    XORB	ZF,!D.{#}S		XORN	D.{#}S	WZ
    
    CLRB	CF			CLR		WC
    CLRB	ZF			CLR		WZ
    				CLR		WC WZ
    
    SETB	CF			SET		WC
    SETB	ZF			SET		WZ
    				SET		WC WZ
    
    NOTB	CF			NOT		WC
    NOTB	ZF			NOT		WZ
    				NOT		WC WZ
    
    MOVB	CF,ZF			MOVZ		WC
    MOVB	CF,!ZF			MOVNZ		WC
    MOVB	ZF,CF			MOVC		WZ
    MOVB	ZF,!CF			MOVNC		WZ
    
    ANDB	CF,ZF			ANDZ		WC
    ANDB	CF,!ZF			ANDNZ		WC
    ANDB	ZF,CF			ANDC		WZ
    ANDB	ZF,!CF			ANDNC		WZ
    
    ORB	CF,ZF			ORZ		WC
    ORB	CF,!ZF			ORNZ		WC
    ORB	ZF,CF			ORC		WZ
    ORB	ZF,!CF			ORNC		WZ
    
    XORB	CF,ZF			XORZ		WC
    XORB	CF,!ZF			XORNZ		WC
    XORB	ZF,CF			XORC		WZ
    XORB	ZF,!CF			XORNC		WZ
    

    The instructions do what they say:
    MOVC	D.S		Move C to D.S
    MOVN	D.S  WZ		Move Not D.S and write Z
    ANDZ	D.S		And Z with D.S
    OR	D.S  WC		Or D.S with C and write C
    MOVC	     WZ		Move C and write Z
    XORNZ        WC		Xor Not Z with C and write C
    
  • jmgjmg Posts: 14,540
    TonyB wrote: »
    ..., inconsistent CF & ZF have had to be contrived

    Sometimes the simplest and most obvious fixes really are the best : Just use C and Z
    A more complex 'fix', usually breaks other things, as in ....
    TonyB wrote: »
    The instructions do what they say:
    MOVC	D.S		Move C to D.S
    MOVN	D.S  WZ		Move Not D.S and write Z
    ANDZ	D.S		And Z with D.S
    OR	D.S  WC		Or D.S with C and write C
    MOVC	     WZ		Move C and write Z
    XORNZ        WC		Xor Not Z with C and write C
    
    Err, oops, actually no they do not... Chip's boolean sub group is much easier to read, especially when mixed in with Register opcodes.

    Your idea has fragmented what was a clear mnemonic sub-group, and scattered operands into three places, and changed the meaning of WC,WZ.

    In all other opcodes, those are optional suffix-only modifiers that control if C,Z are also affected.

    CLR D.{#}S WC
    By P2 convention, that says Clear the operand, and update C, both the BIT and C change.
    The original
    CLRB BitName
    Clears only the named bit. If BitName is Z or C, it is very clear what single bit is affected.
  • jmg wrote: »
    TonyB wrote: »
    ..., inconsistent CF & ZF have had to be contrived

    Sometimes the simplest and most obvious fixes really are the best : Just use C and Z
    A more complex 'fix', usually breaks other things, as in ....
    TonyB wrote: »
    The instructions do what they say:
    MOVC	D.S		Move C to D.S
    MOVN	D.S  WZ		Move Not D.S and write Z
    ANDZ	D.S		And Z with D.S
    OR	D.S  WC		Or D.S with C and write C
    MOVC	     WZ		Move C and write Z
    XORNZ        WC		Xor Not Z with C and write C
    
    Err, oops, actually no they do not... Chip's boolean sub group is much easier to read, especially when mixed in with Register opcodes.

    Your idea has fragmented what was a clear mnemonic sub-group, and scattered operands into three places, and changed the meaning of WC,WZ.

    In all other opcodes, those are optional suffix-only modifiers that control if C,Z are also affected.

    CLR D.{#}S WC
    By P2 convention, that says Clear the operand, and update C, both the BIT and C change.
    The original
    CLRB BitName
    Clears only the named bit. If BitName is Z or C, it is very clear what single bit is affected.

    +1
  • TonyBTonyB Posts: 73
    edited 2017-05-03 - 22:37:53
    jmg wrote: »
    CLR D.{#}S WC
    By P2 convention, that says Clear the operand, and update C, both the BIT and C change.
    The original
    CLRB BitName
    Clears only the named bit. If BitName is Z or C, it is very clear what single bit is affected.

    CLR D.{#}S WC works exactly as before, only the B is missing.

    I think you suggested "." and as long as that is somewhere in D it signifies a bit instruction, there will never be confusion with AND D / OR D / XOR D and B is not needed in the mnemonic.

    Something like ANDZ for AND with Z is no different to ADDC for ADD with carry. If the usage of WC and WZ changes a little for some esoteric instructions will it really matter very much?

    By P1 and P2 convention you can see clearly whenever C or Z are changed through WC and WZ. That was broken and I've fixed it.


  • jmgjmg Posts: 14,540
    edited 2017-05-03 - 22:45:06
    TonyB wrote: »
    If the usage of WC and WZ changes a little for some esoteric instructions will it really matter very much?
    Of course it matters, if the premise used for the change/fragmentation was to preserve convention !!

    The ideal is to make source code easier to read, not add ever-more variances and sub-rules, and scatter and fragment what was a clear sub group of opcodes, which also fails the stated objective ....

    The code Chip already has is perfectly clear, one/two operand assembler, following the simple widely used, core convention of :

    Mnemonic Destination,Source
    Mnemonic Destination


    All of the DOC's use D,S to signify Destination and Source.
  • cgracey wrote: »
    I've got the assembler all updated for the new "d.{#}s" and "!" syntax. I feel funny about how it makes the source code look, as far as knowing that a flag has been modified.

    The BITx instructions with "WC" or "WZ" after them were very easy on the eyes, as there was simplicity and visibility for flag effects. This new way, while much more flexible, requires that you slow way down, in order to tell if a flag has been affected. I almost want to require WC/WF where flag writes are occurring. That way, you'd be able to see, at a glance, where flags are being modified.

    It might be considered a "belt and braces" approach, but given the discussion above it seems that there are (at least) two different code scanning preferences at odds here.

    By requiring the WC/WF flags for the operations where these flags are the destination, you can satisfy (and probably upset) both camps simultaneously.

    It also makes some code completely clear, that might otherwise be unclear:
    ORB     CF, !ZF   WC
    

    No matter which way you scan the code it is clear that this is a bit OR between the Carry Flag and the complement of the Z Flag, stored into the Carry Flag.

    This maintains consistency for the "Destination, Source" paradigm, makes it perfectly clear which operand is complemented, and also uses the WC/WF tags to show the flag modification.

    Both (all) camps see what they are looking for in the code, at the expense of (at most) 2 extra keystrokes per line.

    Of course, this is a tool issue, not a verilog issue, so shouldn't delay silicon production.

    Regards,
    Anthony.
  • requiring the WC/WF flags for the operations where these flags are the destination, you can satisfy (and probably upset) both camps simultaneously

    Agreed.
  • jmgjmg Posts: 14,540
    edited 2017-05-03 - 23:23:43
    AJL wrote: »
    By requiring the WC/WF flags for the operations where these flags are the destination, you can satisfy (and probably upset) both camps simultaneously.

    It also makes some code completely clear, that might otherwise be unclear:
    ORB     CF, !ZF   WC
    

    No matter which way you scan the code it is clear that this is a bit OR between the Carry Flag and the complement of the Z Flag, stored into the Carry Flag.

    This maintains consistency for the "Destination, Source" paradigm, makes it perfectly clear which operand is complemented, and also uses the WC/WF tags to show the flag modification.
    hehe, not sure if that was a serious suggestion, but it works fine for me, combined with a suitably smart assembler.

    Of course, I'd make any half-decent assembler allow aliases and support subsets, so this would also be perfectly legal :
    ; some header.. common Boolean Aliases, if not already inbuilt.
    C  BIT  CF
    Z  BIT  ZF
    
    ORB     C, !Z
    

    The assembler also needs to give an error message on these illegal / not valid variants, if you support/tolerate WC suffix :
    (because the WC WZ rules are not the same as elsewhere, even if the code format may imply it )
    ORB     CF, !ZF   WZ
    ORB     ZF, !CF   WC
    ORB     CF, !ZF   WZ WC
    
  • Hate to say this, but I agree with jmg on this one.
    Changing the meaning of WC/WZ for these is a very bad idea.

    Explicitly calling out the bits involved is the right thing to do. It's more syntax, but it's more clear and leaves WC/WZ to be consistent all around.

  • jmg wrote: »
    AJL wrote: »
    By requiring the WC/WF flags for the operations where these flags are the destination, you can satisfy (and probably upset) both camps simultaneously.

    It also makes some code completely clear, that might otherwise be unclear:
    ORB     CF, !ZF   WC
    

    No matter which way you scan the code it is clear that this is a bit OR between the Carry Flag and the complement of the Z Flag, stored into the Carry Flag.

    This maintains consistency for the "Destination, Source" paradigm, makes it perfectly clear which operand is complemented, and also uses the WC/WF tags to show the flag modification.
    hehe, not sure if that was a serious suggestion, but it works fine for me, combined with a suitably smart assembler.
    Reasonably serious, but I wouldn't fight anyone for it.
    jmg wrote: »
    Of course, I'd make any half-decent assembler allow aliases and support subsets, so this would also be perfectly legal :
    ; some header.. common Boolean Aliases, if not already inbuilt.
    C  BIT  CF
    Z  BIT  ZF
    
    ORB     C, !Z
    
    A warning about the absent WC (or WZ) would be of benefit, simply to ensure that the written code matches the programmer's intention.
    jmg wrote: »
    The assembler also needs to give an error message on these illegal / not valid variants, if you support/tolerate WC suffix :
    (because the WC WZ rules are not the same as elsewhere, even if the code format may imply it )
    ORB     CF, !ZF   WZ
    ORB     ZF, !CF   WC
    ORB     CF, !ZF   WZ WC
    
    Absolutely agree. With these operations the WC and WZ do not represent optional behaviour as they do elsewhere, but would be included to support the humans scanning the code to identify operations that change the flags. The tool can have all it needs without these tags.
    Just like supplying an S operand for any D only operation should give an error, so too using WZ with C as the destination or vice versa should give an error.
  • Really quick, does anyone remember what we were going to rename MIN/MAX/MINS/MAXS to?
  • You guys have been struggling like I have over the syntax of these bit logic instructions. They were really bothering me, as there was no congruous way to meld them into the syntax. I just got rid of them and reverted back to the BITx instructions, harmonizing them with the OUTx/DIRx/DRVx/FLTx instructions.. I'll make logic instructions between C and Z, though.
  • jmgjmg Posts: 14,540
    cgracey wrote: »
    You guys have been struggling like I have over the syntax of these bit logic instructions. They were really bothering me, as there was no congruous way to meld them into the syntax. I just got rid of them and reverted back to the BITx instructions, harmonizing them with the OUTx/DIRx/DRVx/FLTx instructions.. I'll make logic instructions between C and Z, though.
    Noo..... :(
    Are you saying gone is your simple B suffix approach which I thought worked very well, and importantly documents into an easy to grasp and remember block, which is a nice point of difference in the P2, for those new to Boolean coding.

  • cgraceycgracey Posts: 13,125
    edited 2017-05-04 - 04:21:17
    They were great, in their own domain, but they didn't fit syntactically. They felt like a separate processor architecture.
Sign In or Register to comment.