no carry: a=0-(hl)-0 a=0-(hl) If there is no carry, it shouldn’t matter. carry: a=0-(hl)-1 a=-1-(hl) This makes a difference 0-0-1 has a carry, but -1-0 doesn’t.
Looks like a duplicate.
Turning replace restart { jp NC,%1 jp %2 %1: } by { jp C,%2 ; common peephole 79 removed jp by using inverse jump logic %1: } if labelRefCountChange(%1 -1) into } by { jp C,%2 ; common peephole 79 removed jp by using inverse jump logic %1: } if operandsNotRelated(%2 '(hl)' '(ix)' '(iy)'), labelRefCountChange(%1 -1) might suffice, yes.
Though for 4.2.0 the .zxn workaround described above should work.
http://sdcc.sourceforge.net/doc/sdccman.pdf is the official manual. It’s probably also included in the downloads. I used an anchored link directly to the chapter, which doesn’t work anyways if you don’t use the builtin PDF viewer of firefox/chrome. edit: It could be that it generates that warning because sdcc.sourceforge.net doesn’t use https, but not sure. edit2: You probably got that warning because I linked a non-https file from a https site (this ticket system). So it might work when you go directly...
http://sdcc.sourceforge.net/doc/sdccman.pdf is the official manual. It’s probably also included in the downloads. I used an anchored link directly to the chapter, which doesn’t work anyways if you don’t use the builtin PDF viewer of firefox/chrome. It could be that it generates that warning because sdcc.sourceforge.net doesn’t use https, but not sure.
http://sdcc.sourceforge.net/doc/sdccman.pdf is the official manual. It’s probably also included in the downloads. I used an anchored link directly to the chapter, which doesn’t work anyways if you don’t use the builtin PDF viewer of firefox/chrome.
This is a know “bug”. Don’t use named labels, they don’t work when they get embedded into structures that gets translated into jumps. You have to use something like: void test( unsigned int count ) { if ( count == 0 ) return; __asm 2$: ret __endasm; } “3.11.4 Use of Labels within Inline Assembler” explicitly says: All labels defined within inline assembler code have to be of the form nnnnn$ where nnnnn is a number less than 100 The compiler internally uses reusable symbols for all jumps. By introducing...
This is a know “bug”. Don’t use named labels, they don’t work when they get embedded into structures that gets translated into jumps. You have to use something like: void test( unsigned int count ) { if ( count == 0 ) return; __asm 2$: ret __endasm; } “3.11.4 Use of Labels within Inline Assembler” explicitly says: All labels defined within inline assembler code have to be of the form nnnnn$ where nnnnn is a number less than 10 The compiler internally uses reusable symbols for all jumps. By introducing...
SDCC generates invalid opcode "jp NZ, (hl)" for calling a function pointer
Peephole rules 79 - 82 are bugged. They don’t check if the second jump goes to a label. It only gets triggered now because jp (hl) gets generated more. or a, c jp Z, 00103$ call ___sdcc_call_hl 00103$: ret became or a, c jp Z, 00103$ jp (hl) 00103$: ret
Yes, it contains the commit message and a link to the diff.
I even saw error messages when I ran the mingw snapshot with Wine. So it might be something very Windows specific.
Interestingly, I've noted that when sdasz80 reports errors, the REL file is absent. SDAS was modified to remove the .rel file on error. It also ends it’s output with removing Something is significantly going wrong here on Windows, .lst shouldn’t be empty. Maybe it crashes silently before it starts outputting anything. edit: if you use older versions (like 4.2.0) it does work?
Interestingly, I've noted that when sdasz80 reports errors, the REL file is absent. SDAS was modified to remove the .rel file on error. It also ends it’s output with removing Something is significantly going wrong here on Windows, .lst shouldn’t be empty. Maybe it crashes silently before it starts outputting anything.
Somebody else reported as6500 (4.2.0 release) to print no errors. There the .lst file was empty, does that happen for you too?
which version of sdasz80 are you using self compiled But I downloaded 20220401-13349 snapshots for Linux 64bit and Windows 64bit (mingw). I had output for both and ran the windows version with wine. Do you see the errors in the .lst file? u 000733 32 00 00 [13] 1416 ld (#spdcnt),a u 000736 32 00 00 [13] 1417 ld (#trbpsg),a o 000739 1418 if withFade=1 u 000739 32 00 00 [13] 1419 ld (#fading),a q 1420 endif The first character shows the error.
I can’t reproduce this on [r13340] and neither on [r13322]. So this might be a bug that only affects Windows. $ ~/projects/sdcc-code/sdcc/bin/sdasz80 -plff -o BUILD/audio.rel src/audio.s src/audio.s:1416: Error: <u> undefined symbol encountered during assembly src/audio.s:1417: Error: <u> undefined symbol encountered during assembly src/audio.s:1418: Error: <o> .org in REL area or directive / mnemonic error src/audio.s:1419: Error: <u> undefined symbol encountered during assembly src/audio.s:1420:...
Fix regression from [r13318]
I replied by email. apparently it did not come through The notification emails explicitly say: Please do not reply to this message. Post your messages on the original page
Assemblers and Linkers
$ sdasz80 -h -l prints the listing -o creates the rel file, otherwise there would only be a listing -ff is a listing setting that marks relocatable addresses with r 00005C 22r01r00 [16] 203 LD (PT3_MODADDR),HL -p makes the listing print less \f
Fix cycle accuracy for sm83
Improve cycle accuracy for stlcs
Assemblers and Linkers
I get errors ~/projects/sdcc-code/sdcc/bin/sdasz80 -ploff audio.s audio.s:1168: Error: <i> File not found. audio.s:1170: Error: <i> File not found. audio.s:1172: Error: <i> File not found. audio.s:1174: Error: <i> File not found. audio.s:1176: Error: <i> File not found. audio.s:1178: Error: <i> File not found. audio.s:1180: Error: <i> File not found. audio.s:1218: Error: <u> undefined symbol encountered during assembly audio.s:1318: Error: <q> missing or improper operators, terminators, or delimiters...
I get errors ~/projects/sdcc-code/sdcc/bin/sdasz80 -ploff audio.s audio.s:1168: Error: <i> File not found. audio.s:1170: Error: <i> File not found. audio.s:1172: Error: <i> File not found. audio.s:1174: Error: <i> File not found. audio.s:1176: Error: <i> File not found. audio.s:1178: Error: <i> File not found. audio.s:1180: Error: <i> File not found. audio.s:1218: Error: <u> undefined symbol encountered during assembly audio.s:1318: Error: <q> missing or improper operators, terminators, or delimiters...
1 and 2 can certainly be changed. (new asgb accepts that kind of syntax) 3 and 4 are inherently ASxxxx syntax, which can’t be changed, but maybe it’s possible that 4 could be fixed with defines. I’m not sure. The assembler independent part should be the same for sdasz80 and asz80 (macros, if etc.)
Also what do you mean with The assembler is very bare bone and, due to bugs and its odd opcode notation, is not the best to integrate existing libraries in C projects. in your review?
stlcs crashes for divison by zero
Add some test assembly for tlcs90
I’m here on Arch Linux amd64 m4 (GNU M4) 1.4.19 gcc (GCC) 11.2.0 bison (GNU Bison) 3.8.2
Optimize handwritten assembly for tlcs90
tlcs generates iyh
Add partial cycle counting for stlcs
Switch to faster atomic test with shift for tlcs90
stlcs shows placeholder
Since they both trap, I disabled it in [r13296]
Disable undocumented instructions for Z180
Merge error messages from upstream ASxxxx 5.40 for sdas390
Enable .incbin for all targets
Merge error messages from upstream ASxxxx 5.40 for as8051
Should be fixed in [r13287]
AFAIK the z180 does trap on undocumented instructions). What does hd64180 on undocumented instructions? I could throw an error if one tries to enable .allow_undocumented on these targets. But only if that’s the case on hd64180 and z180, because they are the same for asz80.
AFAIK the z180 does trap on undocumented instructions). What does hd64180 on undocumented instructions? I could throw an error if one tries to enable .allow_undocumented on these targets.
Should be fixed in [r13287] .z80 .allow_undocumented sll a ld a, iyl $ sdasz80 test.asm .z80 ;.allow_undocumented sll a ld a, iyl $ sdasz80 test.asm test.asm:3: Error: <a> Undocumented instructions not enabled. test.asm:4: Error: <a> Invalid Addressing Mode.
Fix .allow_undocumented for z80 [bugs:#3275]
case X_Z80: if (rf > S_CPU) rf = 0; break; #define S_CPU 83 #define S_RL_UNDOCD 85 #define X_UNDOCD 89 .allow_undocumented and sll were intentionally or accidentally disabled for z80.
Now it says: test.asm:2: Error: <o> Internal Opcode Error. test.asm:3: Error: <a> Invalid Addressing Mode. I had to fix the error printing first for tracking it down. sdas printed general error messages instead of using the strings actually thrown. Internal Opcode Error means case X_UNDOCD: does not trigger at all.
Fix detailed error messages in sdas
I don’t know where/how to fix the loop optimization and generation, but I also didn’t look into it yet. Here is some demonstration of how it works currently in [r13284] func is not optimized, because the optimization rule does not support this new loop style. func2 is not optimized because it has a function call, which is not supported and documented. But at least it did the comparison at the end of the loop. func3 does the optimization. It’s fine for sm83, but not for z80. Because it decrements...
About reading a byte at hl normally it should be safe Due to in and out there is probably no z80 who uses memory mapping. It looks like it could be worth it to swap b and c and use a similar strategy like we use on GameBoy. That allows to use jrnz in the inner loop, therefore speed that part up significantly. For constants it’s the same size as cpi if hl can’t be trashed. If b and c have to be swapped first and hl is free, it gets bigger in size. _func4:: ld c, a ld de, #0x0030 00104$: inc c dec...
About reading a byte at hl normally it should be safe Due to in and out there is probably no z80 who uses memory mapping. It looks like it could be worth it to swap b and c and use a similar strategy like we use on GameBoy. That allows to use jrnz in the inner loop, therefore speed that part up significantly. For constants it’s the same size as cpi if hl can’t be trashed. If b and c have to be swapped first and hl is free, it gets bigger in size. _func4:: ld c, a ld de, #0x0030 00104$: inc c dec...
I don’t see the benefit if hl can’t be trashed. In my table it’s just slower. cpi 2B 16C ld a,b 1B 4C or a,c 1B 4C Even when transhing hl it’s 2B 16C vs 3B 14C, so it would need to depend on the code optimization settings (speed/size). It might be a problem to have memory at random places be accessed? Since it compares a with (hl)
I don’t see the benefit if hl can’t be trashed. In my table it’s just slower. cpi 2B 16C ld a,b 1B 4C or a,c 1B 4C Even when transhing hl it’s 2B 16C vs 3B 14C, so it would need to depend on the code optimization settings (speed/size).
I don’t see the benefit if hl can’t be trashed. In my table it’s just slower. cpi 2B 16C ld a,b 1B 4C or a,c 1B 4C
I don’t know where/how to fix the loop optimization and generation, but I also didn’t look into it yet. Here is some demonstration of how it works currently in [r13284] func is not optimized, because the optimization rule does not support this new loop style. func2 is not optimized because it has a function call, which is not supported and documented. But at least it did the comparison at the end of the loop. func3 does the optimization. It’s fine for sm83, but not for z80. Because it decrements...
I don’t know where/how to fix the loop optimization and generation, but I also didn’t look into it yet. Here is some demonstration of how it works currently in [r13284] func is not optimized, because the optimization rule does not support this new loop style. func2 is not optimized because it has a function call, which is not supported and documented. But at least it did the comparison at the end of the loop. func3 does the optimization. It’s fine for sm83, but not for z80. Because it decrements...
I don’t know where/how to fix the loop optimization and generation, but I also didn’t look into it yet. Here is some demonstration of how it works currently in [r13284] func is not optimized, because the optimization rule does not support this new loop style. func2 is not optimized because it has a function call, which is not supported and documented. But at least it did the comparison at the end of the loop. func3 does the optimization. It’s fine for sm83, but not for z80. Because it decrements...
No function calls within the loop. No, it shouldn’t. To my knowledge it only works for for (j=0;j<16*3;j++), see [bugs:#3162]
Fix/add cycles of z80 and z80n in sdasz80
There is no manual. And I have no idea how Alan builds the manual for ASxxxx. You sadly have to read the source code. sdcc/sdas/asz80/z80pst.c has the basic mnemonics, that file is pretty short and readable sdcc/sdas/asz80/z80adr.c translates the arguments into symbols, also rather short. *adr.c usually has lists with accepted registers. sdcc/sdas/asz80/z80mch.c handles the cycle counting, opcode emission and is rather long. machine(mp) is the most interesting part and searching for symbols you know...
SM83 devices
Support for undocumented instruction is an sdasz80 extension. asz80 doesn’t have that. It looks like it was added for Z80N and eZ80 (both not supported by upstream) and enabled there by default.
Yes, it looks broken. Since Z80N looks like being a superset of Z80, you could use .zxn as a workaround for handwritten asm. .zxn and .ez80 enable undocumented instructions by default.
Yes, it looks broken. Since Z80N looks like being a superspet of Z80, you could use .zxn as a workaround for handwritten asm. .zxn and .ez80 enable undocumented instructions by default.
The flags only matter for the code generator (?), peephole optimizer and emulator. I’m only focusing on the assembler here. sdasz80 already has extensions for and/add/sub/add/adc/sbc a, ixh/ixl/iyh/iyl inc/dec ixh/ixl/iyh/iyl ld ixh/ixl/iyh/iyl, # ld ixh/ixl/iyh/iyl, r ld r, ixh/ixl/iyh/iyl ld ixh/ixl/iyh/iyl, ixh/ixl/iyh/iyl also sll
SM83 devices
(This only focuses on the first section) Are any instructions of http://www.z80.info/zip/z80-documented.pdf not listed in https://clrhome.org/table/? (undocumented is red) Which are missing? undocumented ixh etc. variants of DD, DDCB, FD, FDCB? Looking at the docu it looks like sll, in (c) is generally missing in upstream. But I would need to study the tests and emitted opcodes. Which opcodes are missing for your existing asm?
There is a rule to optimize it, but it probably depends on a not being used. The new calling convention ends functions that have to clean their arguments from stack withjr (hl) instead of ret. The peephole optimizer can’t say anything about jr (hl), so it assumes a being used.
It is indeed relevant for “possible ways forward include” -mz80 claims to support z80asm and gas, but that would be obviously be without built-in peep hole rules. Switching to a completely different assembler might require splitting z80/z180/z80n/ez80 from rabbit/sm83/tlcs90. Definitely for peep hole rules. (They currently share general rules) More should be discussed in [feature-requests:#791]
Assemblers and Linkers
Assemblers and Linkers
SDCC 4.3.0 Release
--opt-code-size is a compile time optimization. Usually SDCC tries to somewhat balance between size and speed, if you tell it to optimize for one, it will worsen the other.
They don’t, sm83 isn’t considered being a z80 descendant. sm83 doesn’t have DD, FD, ED, DDCB, FDCB. The undocumented instructions in CB are irrelevant, because sm83 has swap there. sm83 is as far as I know more viewed as 8080 with some z80 extensions (CB prefix, jr, N-flag) and z80 mnemonics. And some further custom replacements/additions or things completely removed (S-flag, P-flag, exchange). They probably introduced N to get the fixed daa from z80. jp is different from both z80 and 8080 as it...
They don’t, sm83 isn’t considered being a z80 descendant. sm83 doesn’t have DD, FD, ED, DDCB, FDCB. The undocumented instructions in CB are irrelevant, because sm83 has swap there. sm83 is as far as I know more viewed as 8080 with some z80 extensions (CB prefix, jr, N-flag) and z80 mnemonics. And some further custom replacements/additions or things completely removed (S-flag, P-flag, exchange). They probably introduced N to get the fixed daa from z80. jp is different from both z80 and 8080 as it...
z80instructionSize() failed to parse a label (e.g. '1$:', 'label:')
I opened a request for inline-asm specific labels [feature-requests:#792]
Special variables for inline assembly
SDCC 4.3.0 Release
SDCC 4.3.0 Release
Should work with [r13215]. I skipped the reformating.
Enable new mnemonics on all ports
Eliminate nop jps
This still doesn’t work, you can’t use named labels in inline assembly that way. It becomes: jr Z, 00103$ ;inlineasmtest.c:14: __endasm; label: .db 0x1234 ;inlineasmtest.c:16: fail: 00103$: 00103$ is in the scope of label:, which means jr can’t find it
I was wrong about .ifb, it’s for macros not for direct assignment. SDCC now supports all kinds of .if directives from ASxxxx. I want to reformat the definition files when I enable them for all assemblers, so I’m currently waiting for feedback from upstream in that regard.
Z80 Inline assembler label issue
Fixed in [r13121]
This still doesn’t work, you can’t use named labels in inline assembly that way. It becomes: jr Z, 00103$ ;inlineasmtest.c:14: __endasm; label: .db 0x1234 ;inlineasmtest.c:16: fail: 00103$: 00103$ is in the scope of label:, which means jr can’t find it
ASM warnings
Finally fixed in [r13187]
[z80 family] z80instructionSize misses ascii/str
Fixed in [r13187]
Warning/info: z80instructionSize() failed to parse line node, assuming 999 bytes b_some_banked_func = 2
General ASxxxx syntax in pcDistance
Fixed in [r13187]
For now I had to disable .iif syntax since it can have ops and directives on the right side. Applied in [r13187]
Calculate size of general ASxxx directives, apply [patches:428]