Shop OBEX P1 Docs P2 Docs Learn Events
[resolved][puzzle] High five — Parallax Forums

[resolved][puzzle] High five

kuronekokuroneko Posts: 3,623
edited 2011-04-11 07:02 in Propeller 1
We all know that multiplying by certain small integers is done faster with dedicated code, e.g. multiply by 5 boils down to:
mov     temp, value       ' temp := value
        shl     temp, #2          ' temp := value * 4
        add     temp, value       ' temp := value * 4 + value
For no other reason than to show that it can be done do the same thing with two instructions (8 cycles). As a template use this:
rdlong  value, par        ' read operand
        [COLOR="red"]???[/COLOR]                       ' 1st user instruction
        [COLOR="red"]???[/COLOR]                       ' 2nd user instruction
  • Whatever setup you require should be done before rdlong, this excludes sneak preview(s) by accessing par!
  • Input value and result can be stored in any register you like.
  • For the sake of argument, this code is only called once.

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2011-04-11 00:11
    I guess you said to much when you mentioned "Whatever setup you require should be done before rdlong." ;o)
  • kuronekokuroneko Posts: 3,623
    edited 2011-04-11 00:16
    If times 5 is too easy (I just came up with another solutionA) then try times 3.

    @MagIO: I think I get it now, must be Monday.


    A It's not that I was looking for it, I wanted something else entirely.
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2011-04-11 01:20
    The conditions leave too much space for cheating:
            rdlong value4, par  ' [b]doing whatever setup required :)[/b]
            rdlong value,  par
            shl    value4, #2
            add    value,  value4
    
  • kuronekokuroneko Posts: 3,623
    edited 2011-04-11 01:22
    The conditions leave too much space for cheating
    Fair enough, but since you realised that why do it? :) I added a note regarding this issue.
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2011-04-11 01:28
    Just to point that out :) Formally, that solution satisfied the conditions before they were modified
  • kuronekokuroneko Posts: 3,623
    edited 2011-04-11 01:29
    Formally, that solution satisfied the conditions before they were modified.
    Yes, that's perfectly OK. I wasn't going to turn this solution down. Although I could blame it being Monday :)
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-04-11 03:55
    There is not much that needs to be setup in a prop, so what could it be? ;o)

    But I'm not sure wheather one instruction of the setup has to be counted as being part of the multiplication, as you always have to do it before. Would be interesting to see up to which number this way would be faster than a general purpose solution.
  • kuronekokuroneko Posts: 3,623
    edited 2011-04-11 06:03
    MagIO2 wrote: »
    But I'm not sure wheather one instruction of the setup has to be counted as being part of the multiplication, as you always have to do it before.
    It can be a once-only setup just in case you need some support (e.g. an output pin). The third condition was meant to convey that you don't have to worry about clean-up. If the multiply is repeatable without new setup then that's even better. I do have one version which can be called multiple times once the operand is loaded (mov/rdlong) and another one which would need partial clean-up. For this exercise it doesn't matter. Register N is set and 8 cycles later I want the result.
  • hairymnstrhairymnstr Posts: 107
    edited 2011-04-11 06:16
    Quick idea I had while on lunch, would need some clean up to be repeatable:
    movi    CTRA, #%00100000
    rdlong  FREQA, par
    mov     value, PHSA
    add     value, FREQA
    

    Counter accumulates 4 times per instruction so I'm guessing this should work but not sure.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-04-11 06:23
    'Probably not what you had in mind. :)
          mov     sum,#0
          mov     count,multiplier
          rdlong  value,par
    :loop add     sum,value
          djnz    count,#:loop
    

    -Phil
  • kuronekokuroneko Posts: 3,623
    edited 2011-04-11 06:30
    movi    CTRA, #%0_00100_000
    rdlong  FRQA, par
    mov     value, PHSA
    add     value, FRQA
    
    @hairymnstr: That would be a valid entry for times 3. Well done! phsx is sampled during phase e (SDeR) meaning frqx has only been added twice.

    @Phil, IIRC I mentioned 8 cycles :)
  • hairymnstrhairymnstr Posts: 107
    edited 2011-04-11 06:42
    Blast, I thought there would be some buffering issue. Oh well only got to swap two instructions around a bit and negate one:
    movi    CTRA, #%0_00100_000
    rdlong  FRQA, par
    neg     value, FRQA
    add     value, PHSA
    

    So now the value is made negative in value, then PHSA which should now have 6 times the original value is added to the negative of one times the value.
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2011-04-11 06:49
    Argggh, I am just 5 minutes late :) I was going to post times 3 - and hairymnstr already posted it. Then I have made times 5 - and it is already there.
  • kuronekokuroneko Posts: 3,623
    edited 2011-04-11 06:52
    hairymnstr wrote: »
    So now the value is made negative in value, then PHSA which should now have 6 times the original value is added to the negative of one times the value.
    Which also opens the way for times 7. Nice! Here is my (repeatable) solution for times 5:
    movi    ctra, #%0_11111_000
            rdlong  phsa, par
            mov     frqa, phsa
            mov     frqa, #0
    
  • kuronekokuroneko Posts: 3,623
    edited 2011-04-11 06:57
    And now some rather horrible solution for times 3 or times 5 (as I said, I was after something completely different):
    mov     dira, #%11
            mov     outa, #%01              ' 5:%01, 3:%10
    
            movd    ctra, #1                ' B (A == 0)
            movi    ctra, #%0_01010_000     ' POSEDGE
    
            rdlong  frqa, par
            movi    ctra, #%0_11110_000     ' LOGIC A|B
            movi    ctra, #%0_01010_000     ' POSEDGE
    
  • hairymnstrhairymnstr Posts: 107
    edited 2011-04-11 07:02
    kuroneko wrote: »
    Which also opens the way for times 7. Nice! Here is my (repeatable) solution for times 5:
    movi    ctra, #%0_11111_000
            rdlong  phsa, par
            mov     frqa, phsa
            mov     frqa, #0
    

    Ingenious, so there's no buffering on the frqa register and write is last in the 4 instruction cycle. Very elegant.
Sign In or Register to comment.