flat assembler
Message board for the users of flat assembler.

Index > Non-x86 architectures > AVR tips

Author
Thread Post new topic Reply to topic
shoorick



Joined: 25 Feb 2005
Posts: 1614
Location: Ukraine
shoorick 03 Oct 2016, 07:07
I've noticed there is break command omited in avr.inc.

Code:
macro BREAK?
        dw 1001'0101'1001'1000b
end macro    


also, lds/sts 16-bit are not optimized versions of lds/sts.
I think, they are using in extra reduced devices, which do not have st/ld Z/Y+q,.. commands, as their bitfields are intersected:

Code:
1010 0kkk dddd kkkk - LDS
10q0 qq1r rrrr 0qqq - ST Z+q,..    


I suggest to split lds/sts in avr.inc to sts/lds (regular 2-word command) and sts16/lds16 (one word or 16-bit version).

also, 16-bit versions have tricky addressing: they use 7 bit to address range 0x40-0xBF. to do this, eight bit of address is always equal to inverted seventh bit:

000-0000 = 1000-0000
100-0000 = 0100-0000

finally, bit order in opcode is mixed!:
AVR instruction set wrote:
A 7-bit address must be supplied. The address given in the instruction is coded to a data space address as follows:
ADDR[7:0] = (~INST[8], INST[8], INST[10], INST[9], INST[3], INST[2], INST[1], INST[0])
Memory access is limited to the address range 0x40..0xbf.


so, 0100-0000 adress is coded as:
Code:
XXXXX-00-1-XXXX-0000
bits: 65 7      4321    


a solution may be this:
Code:
macro LDS? Rd,k
        local value,d
        value = +Rd
        if value metadata 1 relativeto R & value scale 2 = 0 & value scale 0 = 0
                d = value metadata 1 - R
                value = +k
                if value >= 0 & value <= 65535
                        dw d shl 4 + 1001000b shl 9
                        dw value
                else
                        err 'address out of range'
                end if
        else
                err 'invalid operand'
        end if
end macro

macro LDS16? Rd,k
        local value,d
        value = +Rd
        if value metadata 1 relativeto R & value eq value element 1
                d = value metadata 1 - R
                value = +k
                if d >= 16 & value >= 0x40 & value <= 0xBF
                        value = value and 0x7F
                        dw value and 1111b + (value and 1000000) shl 2 + (value and 110000) shl 5 \
                           + (r-16) shl 4  + 10101b shl 11
                else
                        err 'address out of range'
                end if
        else
                err 'invalid operand'
        end if
end macro

macro STS? k,Rr
        local value,r
        value = +Rr
        if value metadata 1 relativeto R & value scale 2 = 0 & value scale 0 = 0
                r = value metadata 1 - R
                value = +k
                if value >= 0 & value <= 65535
                        dw r shl 4 + 1001001b shl 9
                        dw value
                else
                        err 'address out of range'
                end if
        else
                err 'invalid operand'
        end if
end macro

macro STS16? k,Rr
        local value,r
        value = +Rr
        if value metadata 1 relativeto R & value eq value element 1
                r = value metadata 1 - R
                value = +k
                if r >= 16 & value >= 0x40 & value <= 0xBF
                        value = value and 0x7F
                        dw value and 1111b + (value and 1000000) shl 2 + (value and 110000) shl 5 \
                           + (r-16) shl 4  + 10101b shl 11
                else 
                        err 'address out of range'
                end if
        else
                err 'invalid operand'
        end if
end macro    


If one wish to use lds mnemonic instead of lds16 he must redefine lds (i'm not sure about better way to do that Rolling Eyes )... and I can not test is as I do not know which device uses those 16-bit versions of lds/sts

_________________
UNICODE forever!
Post 03 Oct 2016, 07:07
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8358
Location: Kraków, Poland
Tomasz Grysztar 03 Oct 2016, 08:16
shoorick wrote:
I've noticed there is break command omited in avr.inc.
This was intentionally omitted, because the HEX output macros use the BREAK that is the instruction of fasm/fasmg (to terminate the WHILE loop) and redefining this as a different instruction would break things. In general a better solution would perhaps be to define a special namespace for the AVR program and define all the instruction handlers inside that namespace only, so the macros outside of that area would have access to original fasmg instruction instead. The other solution that I used elsewhere was not applicable here, because both internal directive and the AVX instruction take no arguments, so it is not possible to write a macro that would behave accordingly depending on the syntax - though it is possible to intercept all WHILE/REPEAT/ITERATE/IRPV loops and change the behavior of BREAK only inside them, and this is relatively simple code, so I'm going to do it this way in the official package:
Code:
AVR_BREAK_INSTRUCTION = 1

macro BREAK?
        if AVR_BREAK_INSTRUCTION
                dw 1001'0101'1001'1000b
        else
                break
        end if
end macro

iterate directive, while,repeat,rept,iterate,irp,irpv

        macro directive?! arguments&
                AVR_BREAK_INSTRUCTION =: 0
                directive arguments
        end macro

        macro end?.directive?!
                end directive
                restore AVR_BREAK_INSTRUCTION
        end macro

end iterate    


shoorick wrote:
lds/sts 16-bit are not optimized versions of lds/sts.
I think, they are using in extra reduced devices, which do not have st/ld Z/Y+q,.. commands, as their bitfields are intersected (...)
I suggest to split lds/sts in avr.inc to sts/lds (regular 2-word command) and sts16/lds16 (one word or 16-bit version).
If these different variants are only available on a different chips, then I think a better way to do it would be to create set of headers for variants of architecture, just like x86 examples have separate headers for 8086, 80186, etc. Note that fasmg's example x86 macros do not define LOADALL286 and LOADALL386 like fasm did, they just have a different LOADALL defined when you include 80286.inc, and different one in 80386.inc, and none in files for other processors.

For now I'm just removing this other variant of LDS/STS from the example. It might have been my over-zeal to demonstrate fasm's abilities of instruction length optimization that led to inclusion of all these variants at once.

In the nearest future I don't think I will be able to put enough effort into examples for other architectures to bring them to the level of x86 ones (I still need much more time to finish x86, as there are still more extensions that I would like to include). It would be great if there happened to be someone more interested in making some usable set of headers for AVR - I would assist in any efforts.
Post 03 Oct 2016, 08:16
View user's profile Send private message Visit poster's website Reply with quote
shoorick



Joined: 25 Feb 2005
Posts: 1614
Location: Ukraine
shoorick 03 Oct 2016, 08:27
Tomasz Grysztar wrote:
This was intentionally omitted, because the HEX output macros use the BREAK that is the instruction of fasm/fasmg (to terminate the WHILE loop) and redefining this as a different instruction would break things.
I see... I'll just use break_ then to not conflict with built-in break - it has to be enough Smile

and why remove those lds/sts 16-bit versions at all? just add them as lds16/sts16 as if somebody occasionally meet neccesity in them Wink

thanks!

_________________
UNICODE forever!
Post 03 Oct 2016, 08:27
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8358
Location: Kraków, Poland
Tomasz Grysztar 03 Oct 2016, 08:40
shoorick wrote:
and why remove those lds/sts 16-bit versions at all? just add them as lds16/sts16 as if somebody occasionally meet neccesity in them Wink
The instruction set manual does not use a separate mnemonics for them - they should be available under the same name, only in a context of different target device. I think this is something that should be left up to a more complex header set that we hopefully may create one day.
Post 03 Oct 2016, 08:40
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.