flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > Z80 jumps auto optimization |
Author |
|
Tomasz Grysztar 05 Jan 2016, 17:43
One of the fundaments of fasm's architecture is its code resolving ability, which from my point of view is so important for an assembler than I even based my own definition of what an assembler is on this feature. In simple terms, code resolving allows you to forward-reference various values (like label addresses) and thus create interdependent definitions, like an equation - and the assembler must find a solution.
Because fasm's code resolving applies universally to all kinds of constructions, a macro that utilizes it to optimize the instruction sizes may be as simple as this: Code: ; fasm 1 syntax macro jrp address { if address-$ <= 127 & address-$ >=-128 jr address else jp address end if } If you would like to see the real implementation of instruction encoding optimization though macros, please check out the new fasm g package. It contains implementation of x86 instructions in form of macros and they optimize opcodes (not only jumps, but other instructions that have multiple encodings as well) the same as native implementation of fasm 1 does. Also the macro sets that implement 8051 and AVR architectures contain JMP implementations that optimize jump lengths, because I wanted to demonstrate this basic fasm's ability wherever possible. AFAIK there does not yet exist an implementation of Z80 instruction set for fasm g - but I hope we may get one in the future. And it should have opcode length optimization, of course. |
|||
05 Jan 2016, 17:43 |
|
marste 05 Jan 2016, 19:38
GREAT STUFF Tomasz!!!
(referring to fasmg) Last edited by marste on 24 Jul 2017, 17:15; edited 1 time in total |
|||
05 Jan 2016, 19:38 |
|
shutdownall 05 Jan 2016, 23:44
Thanks for this macro, Tomasz.
In fact I am not a fan of these automatic jumps and would use short jumps only in a short context and use far jumps more general. This is one byte more for the target but even 20% faster executed. But this is maybe my philosophy only. In my programs I use JR (short jump) mostly together with anonymous labels which is really a very nice solution from flat assembler. |
|||
05 Jan 2016, 23:44 |
|
marste 09 Jan 2016, 01:21
As you know I'm choosing JR mostly for space saving reasons, but anyway as of my knowledge they are even 30% faster when there are conditional jump not executed (7 tstates vs 10)
|
|||
09 Jan 2016, 01:21 |
|
shoorick 09 Jan 2016, 06:53
IMHO, such kind of optimization should be controlled. There is not distance, size and clocks difference only.
I had not coding fo Z80 exactly, but I know relative jumps are important for portable code (independent of memory location). It is better to get error message than get inexpectively non-portable binary. ++++++++++++++++ A variable like "optimize" can be used for such kind of control If it is not defined or set to zero there should be no any optimization, if set - then optimization used. there could be more complex kinds of optimisations etc. (until all silicon Z80 will disappear ) |
|||
09 Jan 2016, 06:53 |
|
Tomasz Grysztar 09 Jan 2016, 09:35
A macro that marste proposed (JRP) would not interfere with the standard JR and JP instructions, you'd only use it where you wanted it.
On the other hand, whether one should care about leaving the code position-independent when it has fixed loading address is a subject of debate on this board. |
|||
09 Jan 2016, 09:35 |
|
marste 09 Jan 2016, 10:03
Adapted a bit the macro. The version able to manage also conditional jump is:
Code: ; jr if possible, else jp ; eg: ; jrp address ; jrp nz,address macro jrp op1,op2 { if op2 eq if op1-$ <= 127 & op1-$ >=-128 jr op1 else jp op1 end if else if op2-$ <= 127 & op2-$ >=-128 jr op1,op2 else jp op1,op2 end if end if } Used in 5 places and was able to optimize one more byte in respect to my manual work! lol @Tomasz If it is not urgent and you give some guideline I can try to adapt fasm_g to Z80. Would be nice to be able to compile optimal Z80 code under linux![/code] |
|||
09 Jan 2016, 10:03 |
|
Tomasz Grysztar 09 Jan 2016, 11:01
marste wrote: @Tomasz For the basic instructions that take no operands, the macro can be as simple as: Code: macro NOP?
db 0
end macro When an instruction has a fixed set of simple syntaxes, you can handle them all with MATCH directive: Code: macro EX? first,second match (=SP?), first match =HL?, second db 0E3h else match =IX?, second db 0DDh,0E3h else match =IY?, second db 0FDh,0E3h else err "invalid second operand" end match else match =AF?, first match =AF'?, second db 08h else err "invalid second operand" end match else match =DE?, first match =HL?, second db 0EBh else err "invalid second operand" end match else err "invalid operand" end match end macro EX (SP),HL EX (SP),IX EX AF,AF' EX DE,HL When the registers from a larger set are allowed, you can use ELEMENT directive and then extract the register number from element's metadata - like it is done in the samples in fasmg package. But, to be honest, unless you need to process the arithmetic expressions containing register names (like I do it for x86 addressing modes) you may find the ELEMENT-based processing unnecessarily complex and it may be simpler to use just an assisted MATCH syntax based on some special constructions, like: Code: A? equ [:111b:] B? equ [:000b:] C? equ [:001b:] D? equ [:010b:] E? equ [:011b:] H? equ [:100b:] L? equ [:101b:] macro INC? operand match [:r:], operand db 100b + r shl 3 else match (=HL?), operand db 34h else match (=IX?+d), operand db 0DDh,34h,d else match (=IY?+d), operand db 0FDh,34h,d else err "invalid operand" end match end macro INC A INC B INC (HL) INC (IX+2) Code: A? equ [:111b:] B? equ [:000b:] C? equ [:001b:] D? equ [:010b:] E? equ [:011b:] H? equ [:100b:] L? equ [:101b:] element HL? element IX? element IY? macro INC? operand match [:r:], operand db 100b + r shl 3 else match (a), operand if a relativeto HL & a = HL db 34h else if a relativeto IX db 0DDh,34h,a-IX else if a relativeto IY db 0FDh,34h,a-IY else err "invalid operand" end if else err "invalid operand" end match end macro INC (3*8+IX+1) x = IX+3 INC (x) With these samples in mind I think you should be able to implement a complete instruction set. What syntax variants would you allow in your macros is all up to you. And when you have a complete instruction set ready, the next step would be to add some macros for generating the right output format. Please ask if you have any questions. |
|||
09 Jan 2016, 11:01 |
|
shoorick 09 Jan 2016, 15:51
Tomasz Grysztar wrote: On the other hand, whether one should care about leaving the code position-independent when it has fixed loading address is a subject of debate on this board. he-he exactly! some kind of applications on Z80/i8080 was made position-independant (or self-relocated, or even more correct: self updating for current location) exactly due to ability to load and run in any location, selected by user. those were mostly debuggers, compressors or other kind of service tools, loaded to free space to not intersect with regular application, loaded at fixed address i8080 has no relative jumps, so, there were tricks used to guess current offset by application. _________________ UNICODE forever! |
|||
09 Jan 2016, 15:51 |
|
shutdownall 09 Jan 2016, 16:07
If you want relocatable code it is not an easy task if the operating system does not support this by default. You should also keep in mind that this affects not only jumps but access of data as well. For the target used (ZX81) there are even several registers (index registers) which are unusable as used from the system rom which makes it more hard to code address independent.
Anyway this would conflict with the restriction of 1kB only for programs including system variables and display content as used for the ZX81. The display file (if full screen used) takes up to 768 byte plus about 100 bytes for system variables - so not worth to think about relocatable code for this use cases with 1 kB memory at all. So the macro did at last press one more byte space - I would have expected more. Yes - anybody might port the fasmg to Z80, this is really fun I think. As the ZX-IDE (FASMW-ZX) does support not only Z80 code but BASIC structures of ZX81 and ZX80, too (plan to do a direct port of ZX Spectrum as well) and I want to have a nice one and only tool I made this special version. This is an editor with some tools which can compile as well which is quite different to a tool chain which I personally don't like at all. We are in 2016 now and people may force me to work like we are in the 1980s - no thanks. That's why I don't use and don't like Linux which is too much tinkering in my eyes. Now I am working under OS X and use FASMW-ZX with VirtualBox on my Apple Mac together with other tools not available under OS X like Eprom Programmers, Logic Analyzer, USB Blaster and so on. So fasmg is quite nice but for me personally no choice as a development tool. And I put quite much development in FASMW-ZX so not really interested in beginning again at point zero. |
|||
09 Jan 2016, 16:07 |
|
marste 09 Jan 2016, 19:44
shutdownall wrote: So the macro did at last press one more byte space - I would have expected more. It seems I was doing a good work also manually! |
|||
09 Jan 2016, 19:44 |
|
shoorick 10 Jan 2016, 11:31
well, then I reduce my explanation into shorter form: if I open z80 book and see: JP match to 0C3h opcode, then I must see 0C3h in binary ever. Anything other better, shorter or faster etc. must be optional and turned on explicitly, except you write macros/assembler for yourself only.
|
|||
10 Jan 2016, 11:31 |
|
marste 10 Jan 2016, 12:29
Jrp is a completely new instruction (not already opcoded) for programmers to use if they want (and need)!... [/u]
|
|||
10 Jan 2016, 12:29 |
|
shoorick 10 Jan 2016, 13:14
no, jrp is not an instruction, it is optimizing macro, and I agree with this form, as it is explicit extension
|
|||
10 Jan 2016, 13:14 |
|
marste 15 Feb 2016, 15:34
PS the "little" project keeping me busy released: https://sourceforge.net/p/smmax/blog/2016/02/real-chess-for-the-zx81-1k/
|
|||
15 Feb 2016, 15:34 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.