Shop OBEX P1 Docs P2 Docs Learn Events
Assembler help needed ( 64-bit negation ) — Parallax Forums

Assembler help needed ( 64-bit negation )

hippyhippy Posts: 1,981
edited 2007-12-30 14:35 in Propeller 1
Can anyone please help optimise this ( ie, fewer instructions ) ...

                shr     :signBit,#1 WC, NR
        IF_C    xor     :accTop,k_FFFF_FFFF
        IF_C    xor     :accBot,k_FFFF_FFFF
        IF_C    add     :accBot,#1 WC
        IF_C    add     :accTop,#1





The two 32-bit registers make a two's complement 64-bit number accTop:accBot and if lsb of signBit is set I want to negate those 64-bits. I'm using 'invert add one' but there's got to be a better way.

There's a whole raft of NEG opcodes but I can't see any which would help me, negating accTop and negating accBot isn't quite the same as negating accTop:accBot.

Comments

  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-30 05:26
    Does this work? No
    [s]               test :signbit,#1 wz
    if_z           neg :accBot,:accBot wc
    if_z           neg :accTop,:accTop
    if_z_and_nc sub :accTop,#1
    [/s]
    
    



    Shorter by one instruction and one constant if so.

    Alternatively perhaps: Nuh huh
    [s]
                   test :signbit,#1 wz
    if_z           neg :accBot,:accBot wc
    if_z           xor :accTop,k_FFFF_FFFF
    if_z_and_c add :accTop,#1
    [/s]
    
    



    Shorter by one instruction.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Play Defender - Propeller version of the classic game
    Prop Room Robotics - my web store for Roomba spare parts in the UK

    Post Edited (CardboardGuru) : 12/30/2007 11:25:46 AM GMT
  • Beau SchwabeBeau Schwabe Posts: 6,559
    edited 2007-12-30 07:01
    hippy,
    I tried your code, and I understand that "negating accTop and negating accBot isn't quite the same as negating accTop:accBot", but wouldn't this work?
    [s]                shr     :signBit,#1 WC, NR
                    negc    :accTop,:accTop
            IF_C    sub     :accTop, #1
                    negc    :accBot,:accBot[/s]
    

    ·Edit - never mind, I did not take into account overflow with accBot



    CardboardGuru,

    I tried your code, which both versions appear to have the same end result, but I noticed that·'accTop'·gets inverted·with a "1" added to it in both circumstances.







    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 12/30/2007 7:12:42 AM GMT
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-30 11:15
    Hi Beau,

    Yes, bad assumption about what the carry flag would do after a neg. I was thinking it would act as a carry for the add one(neg being invert and add one). In fact it acts as a sign indicator. Silly me. Must always check.

    If neg doesn't give a proper carry for the add one, then it can't be any use for multi-long negs. So explicit invert and add with carry on both longs it is, and Hippy already has the tightest version.

    ...Unless someone's got something really cunning...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Play Defender - Propeller version of the classic game
    Prop Room Robotics - my web store for Roomba spare parts in the UK

    Post Edited (CardboardGuru) : 12/30/2007 11:22:00 AM GMT
  • hippyhippy Posts: 1,981
    edited 2007-12-30 14:10
    I'm glad it wasn't just me finding it harder than I thought it should be !

    I think I might have solved it, original code ...

                    shr     :signBit,#1 WC, NR
        IF_C        xor     :accTop,k_FFFF_FFFF
        IF_C        xor     :accBot,k_FFFF_FFFF
        IF_C        add     :accBop,#1 WC
        IF_C        add     :accTop,#1 
    
    



    Replacing the 'invert add one' of accBot with neg and imagining there is a carry (X) that did behave as we'd like, one gets ...

                    shr     :signBit,#1 WC, NR
        IF_C        xor     :accTop,k_FFFF_FFFF
        IF_C        neg     :accBop,:accBot WX
        IF_C_AND_X  add     :accTop,#1 
    
    



    As neg is 'invert add one' the carry (X) we'd like to get would only be set when the resulting neg accBot == 0, thus Z is the carry bit.

                    shr     :signBit,#1 WC, NR
        IF_C        xor     :accTop,k_FFFF_FFFF
        IF_C        neg     :accBop,:accBot WZ
        IF_C_AND_Z  add     :accTop,#1 
    
    



    To save on the long constant, neg then sub should also work ...

                    shr     :signBit,#1 WC, NR
        IF_C        neg     :accTop,:accTop
        IF_C        neg     :accBop,:accBot WZ
        IF_C_AND_NZ sub     :accTop,#1 
    
    



    I think you both got incredibly close and weren't that far off solving it yourselves. I cheated by putting a good night's sleep between then and now smile.gif

    My question now is ... how do I test it to destruction to prove it works ?
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-30 14:35
    hippy said...

    As neg is 'invert add one' the carry (X) we'd like to get would only be set when the resulting neg accBot == 0, thus Z is the carry bit.

    Eureka!
    hippy said...
    My question now is ... how do I test it to destruction to prove it works ?

    I make it 85 million days* (233 millennia) to test on one cog. You could always throw more cogs at it! wink.gif

    (* though I might have slipped up on the odd order of magnitude here or there.)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Play Defender - Propeller version of the classic game
    Prop Room Robotics - my web store for Roomba spare parts in the UK

    Post Edited (CardboardGuru) : 12/30/2007 2:41:36 PM GMT
Sign In or Register to comment.