Shop OBEX P1 Docs P2 Docs Learn Events
BITL D,{#}S {WCZ} Syntax question — Parallax Forums

BITL D,{#}S {WCZ} Syntax question

Following info from PASM instruction Spreadsheet:
BITL D,{#}S {WCZ}
Bits D[S[9:5]+S[4:0]:S[4:0]] = 0. Other bits unaffected. Prior SETQ overrides S[9:5]. C,Z = original D[S[4:0]]. 

SETQ
Set Q to D. Use before RDLONG/WRLONG/WMLONG to set block transfer. Also used before MUXQ/COGINIT/QDIV/QFRAC/QROTATE/WAITxxx. (Doesn't Mention BITL instruction)

The question in reference to above documentation is where is the "Q" register is it in each Cog ? I can't seem to find it listed as a Hardware register constant.

Reason I am asking how does SETQ overide S[9:5] in BITL instruction and what sort of purpose would this be used. I am just working through the instruction one at atime. I may be getting beyond my present understanding. (Haven't even attempted to understanding streaming just working on trying to get familiar with PASM instructions) If this needs some more in depth
knowledge that what a Noobie requires just say "move on for the present time". Thanks for your time
Regards
Bob (WRD)

Comments

  • evanhevanh Posts: 15,915
    edited 2021-08-01 01:12

    Q is a hidden special purpose register inside the cog's processor core (ALU). The Program Counter (PC) is another one of these. Q also must have a couple of associated flags to tell subsequent instructions that Q has just been refreshed. At least two flags are needed for RDLONG/WRLONG to know if they should burst read/write to cogRAM or lutRAM.

    EDIT: Oh, of course, SETQ sets first flag and SETQ2 sets the second flag.

  • evanhevanh Posts: 15,915

    SETQ works differently to the ALTx instructions. SETQ fills the Q register and sets a flag as future notification. ALTx instructions modify the already fetched next instruction inside the pipeline.

  • evanhevanh Posts: 15,915
    edited 2021-08-01 01:23

    So BITL will have logic to detect the notification flag and change its data source for S[9:5] to Q[??:??]. Best guess is Q[4:0].

    • Notification will auto-clear,
    • Q retains last set value.
    • Section named "SETQ CONSIDERATIONS" details other uses of Q register beyond SETQ/SETQ2.
  • Bob, this is something you probably don’t need to worry too much about.
    The only use for the prior SETQ for BITL is to adjust the number of pins/bits affected by the instruction. S[4:0] will still set the base pin/bit, and Q will then determine how many additional pins/bits.

    An example used might be for adaptable code to clear a variable number of bits in D based on the results of earlier code, or a runtime configuration value.

  • evanhevanh Posts: 15,915

    Lol, ALTing an ALT works.

  • evanhevanh Posts: 15,915
    edited 2021-08-01 05:22

    When I first ran this I was scratching my head ... but it really works!

            alts    misc2, misc2
            alts    misc2, #20
            mov ptrb, #25
            ...
    
    misc2       long    1 | (3<<9)
    
    • First ALTS sums 1 + 1 and replaces the #20 with a #2 in the second ALTS. misc2[8:0] is updated to 4 (1 + 3).
    • Second ALTS sums 2 + 4 and replaces the #25 with a #6 in the MOV. misc2[8:0] is unchanged.
    • MOV then places value of #6 in PTRB.

    PS: This wasn't for anything useful. I'm only trying to break the hardware.

  • TonyB_TonyB_ Posts: 2,178
    edited 2021-08-02 09:32

    Using S[9:5] to specify a group of contiguous bits was a late change to BITL and other bit instructions. Often S[8:5] will be enough and therefore a 9-bit immediate can be used.

    How long does SETQ/SETQ2 "live" (flag, not value)? If followed by an instruction that doesn't use it (excluding ALTx/AUGx), is it cancelled or will it persist until an instruction that does use it?

  • It might help to use:
    D[BH:BL] = D[S[9:5] + S[4:0] : S[4:0]] = 0 where BH is high bit to be zero and BL the low bit to be zero of the group of zero bits
    Example D[23:16] =0 Let D[31:0] =$FFFF_FFFFF
    We want the following Pattern:
    D[31:0] = 11111111_00000000_11111111_11111111 BH = 23 BL =16
    then S[9:5] + S[4:0] = 23 S[9:5] = 23 - S[4:0] = 23-16 =7 Then S[31:10] = 0 S[9:5] =7 S[4:0] = 16 S=%00000000_00000000_00000000_111_10000 = 240

    Just adding this because it is a little confusing first time through.seems to work .
    Regards
    Bob (WRD) .

  • Bob, if that helps you understand it then that's good.

    I'd make one small adjustment to avoid future confusion:
    S=%00000000_00000000_000000_00111_10000

    It might seem a small thing, but given there is a 5 bit field to add up 31 extra bits, it makes sense to partition the word that way. Also note that the bitfield will wrap within the word.

    The ADDPINS/ADDBITS element of SPIN2 uses this functionality, which is specified as BL ADDBITS NUMBITS
    In your example that would look like
    MyVar.[16 ADDBITS 7] which would be equivalent to MyVar.[%00111_10000]

    Hope this hasn't caused any confusion.

  • evanhevanh Posts: 15,915
    edited 2021-08-02 07:05

    @TonyB_ said:
    How long does SETQ/SETQ2 "live" (flag, not value)? If followed by an instruction that doesn't use it (excluding ALTx), is it cancelled or will it persist until an instruction that does use it?

    Regular instructions, even ones that have no use for Q, will all consume the flag. Instructions that won't consume the flag are the special prefixing ALTx and AUGx. Not sure what else.

  • @"Bob Drury" said:
    It might help to use:
    D[BH:BL] = D[S[9:5] + S[4:0] : S[4:0]] = 0 where BH is high bit to be zero and BL the low bit to be zero of the group of zero bits

    For immediate S, I think it would help if the assembler could support #S split into two, as follows :
    BITL D,#S_low,#S_high {WCZ}
    where #S_low = low bit of group and #S_high = group size (= 1 if #S_high omitted).

    Example to zero byte 2
    BITL D,#16,#8
    although SETBYTE could also be used in this case.

  • @TonyB_ said:

    @"Bob Drury" said:
    It might help to use:
    D[BH:BL] = D[S[9:5] + S[4:0] : S[4:0]] = 0 where BH is high bit to be zero and BL the low bit to be zero of the group of zero bits

    For immediate S, I think it would help if the assembler could support #S split into two, as follows :
    BITL D,#S_low,#S_high {WCZ}
    where #S_low = low bit of group and #S_high = group size (= 1 if #S_high omitted).

    Example to zero byte 2
    BITL D,#16,#8
    although SETBYTE could also be used in this case.

    You can just do
    BITL D,#8 addbits 7

  • AJl
    S=%00000000_00000000_000000_00111_10000
    Yes that is better I will put in notes.
    Regards
    Bob (WRD)

Sign In or Register to comment.