The best way to see what the problems are is to try to write the code by hand that the compiler will have to write ahead of a function call. Use a real compiler-generated assembly listing and try to modify code leading into those calls to use fastcall linkage like this. The issue with forcing the compiler to place values into registers is that as registers are given their values, the compiler can no longer use those registers to gather more values. This leads to a lot of code ahead of the call.
So in "void PutPixel3D (int x, int y, int z)" after putting x into HL, the compiler can no longer use HL to put y into DE. After it puts y into DE the compiler cannot use HL or DE to put z into BC. The code will be poor unless x,y,z are static variables. This is what I meant by the callee linkage being quite a good compromise -- because it allows the parameters to be gathered without register restriction and it only costs 21 cycles / 2 bytes for the push before the function call and the pop inside the function. Better, the called function can pop the values into the registers it needs them in whereas using a fastcall linkage like this the called function will have to shuffle the registers into the correct destination registers.
You might be thinking that the parameter gathering into registers from local values is not a big deal since it can be done easily with (ix+d) offsets. But the compiler needs to stay away from ix as much as possible to get any sort of decent performance or decent code size. sdcc tries to keep things in registers, as it should, and only spills to (ix+d) or the stack when it has to. If it has to gather values into specific registers, I think you will see a lot more pushing/popping to save registers or even storing in temporaries created by the compiler and indexed by ix, which is what sdcc does when it has too many variables in its working set.
In specific circumstances like gathering two chars into HL, it's very a likely a win but I'm not too enthusiastic about other cases for the reasons mentioned above.
[свернуть]