Shop OBEX P1 Docs P2 Docs Learn Events
efficient compare and jump in SX assembly — Parallax Forums

efficient compare and jump in SX assembly

Keith MKeith M Posts: 102
edited 2008-10-17 15:45 in General Discussion
I've got an 8-bit variable where ranges of values have significance. I want the code to make decisions based on the value, and jump to the respective code block.

There are basically five ranges of significance:

Case A: Values less than 81.

Case B: Values between 81 and 106.
Case C: Values between 131 and 156.
Case D: Values between 181 and 206.

Case E: Values over 206.

I'm well aware of the CJx(x) instructions, which would work perfect, except that they are relatively expensive. There is always going to be a match, and there are always going to be a certain number of failed compares before that which will cost cycles. Cases B-D will occur much more frequently than the other two which are error conditions. There will likely NOT be a popular or most occurring choice of the three.

The CSx(x) instructions are valuable too, but they can't easily be daisy-chained due to the fact that the skip is only a single word skip. (and the CS instructions are multiword)

These values aren't super strict. So if I check values of 80 - 112, because they can be easily constructed with the top four bits, then that's ok. So I guess expanding the ranges slightly is ok, but reducing them I'd have to be a bit more careful in how I do that.

I've thought about doing a binary search tree based on the most 4 significant bits so something like this:


SB tmpvalue.7
JMP handlelessthan128

'values here are 128 or larger

SNB tmpvalue.6
JMP handlemorethan192

'values here are between 128 and 192

SNB tmpvalue.5
JMP handlemorethan160

'values here are between 128 and 160
'handle Case C here

----------
handlessthan128:

'if bits 6 and 4 are set, handle Case A

-----------
handlemorethan192:

........etc.....etc




Is this approach the best? I like the fact that the SB/SNB instructions are 1 or 2 cycles, and that JMP is a single-word instruction.

Thanks.

Keith

Comments

  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2008-10-13 06:23
    Hi Keith,

    in your post, you did not mention where execution should go when the variable lies between one of the ranges you have specified, i.e. if the variable would be 110, for example. Without "gaps" between the ranges, the following code might be an alternative:

    mov w,  Value
        
        sub w,  #81
        sc
          jmp   CaseA
        sub w,  #25
        sc
          jmp   CaseB
        sub w,  #50
        sc
          jmp   CaseC
        sub w,  #50
        sc
          jmp   CaseD
      
    CaseE
    ;...
    CaseA
    ;...
    CaseB
    ;...
    CaseC
    ;...
    CaseD
    ;...
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • Keith MKeith M Posts: 102
    edited 2008-10-13 17:21
    Guenther,

    Thanks for taking the time to respond.

    This looks like this will work fine. The gray-area undefined areas are unlikely to show up unless stuff is seriously out of spec, but having the software do SOMETHING with those values is probably valuable.

    I'm probably doing something wrong, but in the latest version of the IDE,

    sub w, #81
    
    



    doesn't assemble. I checked the SX-key development system manual, page 142 for SUB and it doesn't appear that SUB W, #literal is an available choice.

    Obviously I'll just use another variable other than W. I don't see anything else in your code that requires the value be in w.

    Thanks

    Keith
  • BeanBean Posts: 8,129
    edited 2008-10-13 18:52
    Keith,
    You are right. The only SUB instruction is "SUB fr,W", so you cannot subtract a value from W.
    You'll need to use a temporary variable.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    "It is our choices, Harry, that show what we truly are, far more than our abilities."·Dumbledore from Harry Potter

    www.iElectronicDesigns.com

    ·
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-10-14 02:05
    Well, there's also MOV W,fr-W, a reverse subtraction.

    In the SX, there are no arithmetic operations whose operands are literals. Those didn't come along until the 14-bit PIC instruction set debuted. (The SX is based on the 12-bit PIC instruction set.)

    -Phil
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2008-10-15 23:18
    Keith,

    I'm sorry about my mis-leading example - must have been pretty late here, when I posted it.

    You all are right, the SX does not allow for a SUB w, #constant instruction. I think, using the MOV W, fr-W instruction as Phil suggested might be the next best alternative.

    Assuming that 'Value' contains the value to control the program flow, you may use constructs like

    mov w, #81
    mov w, Value-w
    sc
    jmp CaseA

    to test if Value is below a certain limit.

    The nice feature of the mov w, fr-w instruction is that the original contents of fr remains unchanged.

    If you would use a construct like

    sub Value, #81

    which actually is a sequence of

    mov w, #81
    sub Value, w

    instead, the original contents of Value would be lost after the sub. Nevertheless, you still have the option using a sequence of subtractions like in my "theoretical" example to check if a value falls into certain ranges.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • Keith MKeith M Posts: 102
    edited 2008-10-17 15:45
    Thanks Guenther and everyone for the replies.

    Keith
Sign In or Register to comment.