- else {
- /* make the call */
- char *name = OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
- OP_SYMBOL(IC_LEFT(ic))->rname :
- OP_SYMBOL(IC_LEFT(ic))->name;
- emitcode("call", "%s", name);
- if (!strcmp(name, "__printf"))
- isPrintf = 1;
-
- }
-
- /* if we need assign a result value */
- if ((IS_ITEMP(IC_RESULT(ic)) &&
- (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
- OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
- IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
-
- accInUse++;
- aopOp(IC_RESULT(ic),ic,FALSE);
- accInUse--;
-
- assignResultValue(IC_RESULT(ic));
-
- freeAsmop(IC_RESULT(ic),NULL, ic);
- }
-
- /* adjust the stack for parameters if required */
- if (IC_LEFT(ic)->parmBytes) {
- int i = IC_LEFT(ic)->parmBytes;
- emitcode("", ";parmBytes = %u\n", i);
- if (isPrintf)
- i+=2;
- _pushed -= i;
- if (i>6) {
- emitcode("ld", "hl,#%d", i);
- emitcode("add", "hl,sp");
- emitcode("ld", "sp,hl");
- }
- else {
- while (i>1) {
- emitcode("pop", "hl");
- i-=2;
+
+ _saveRegsForCall(ic, _G.sendSet ? elementsInSet(_G.sendSet) : 0);
+
+ /* if send set is not empty then assign */
+ if (_G.sendSet)
+ {
+ iCode *sic;
+ int send = 0;
+ int nSend = elementsInSet(_G.sendSet);
+ bool swapped = FALSE;
+
+ int _z80_sendOrder[] = {
+ PAIR_BC, PAIR_DE
+ };
+
+ if (nSend > 1) {
+ /* Check if the parameters are swapped. If so route through hl instead. */
+ wassertl (nSend == 2, "Pedantic check. Code only checks for the two send items case.");
+
+ sic = setFirstItem(_G.sendSet);
+ sic = setNextItem(_G.sendSet);
+
+ if (_opUsesPair (IC_LEFT(sic), sic, _z80_sendOrder[0])) {
+ /* The second send value is loaded from one the one that holds the first
+ send, i.e. it is overwritten. */
+ /* Cache the first in HL, and load the second from HL instead. */
+ emit2 ("ld h,%s", _pairs[_z80_sendOrder[0]].h);
+ emit2 ("ld l,%s", _pairs[_z80_sendOrder[0]].l);
+
+ swapped = TRUE;
+ }
+ }
+
+ for (sic = setFirstItem (_G.sendSet); sic;
+ sic = setNextItem (_G.sendSet))
+ {
+ int size;
+ aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+
+ size = AOP_SIZE (IC_LEFT (sic));
+ wassertl (size <= 2, "Tried to send a parameter that is bigger than two bytes");
+ wassertl (_z80_sendOrder[send] != PAIR_INVALID, "Tried to send more parameters than we have registers for");
+
+ // PENDING: Mild hack
+ if (swapped == TRUE && send == 1) {
+ if (size > 1) {
+ emit2 ("ld %s,h", _pairs[_z80_sendOrder[send]].h);
+ }
+ else {
+ emit2 ("ld %s,!zero", _pairs[_z80_sendOrder[send]].h);
+ }
+ emit2 ("ld %s,l", _pairs[_z80_sendOrder[send]].l);
+ }
+ else {
+ fetchPair(_z80_sendOrder[send], AOP (IC_LEFT (sic)));
+ }
+
+ send++;
+ freeAsmop (IC_LEFT (sic), NULL, sic);
+ }
+ _G.sendSet = NULL;
+ }
+
+ if (ispcall)
+ {
+ if (IS_BANKEDCALL (detype))
+ {
+ werror (W_INDIR_BANKED);
+ }
+ aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+
+ if (isLitWord (AOP (IC_LEFT (ic))))
+ {
+ emit2 ("call %s", aopGetLitWordLong (AOP (IC_LEFT (ic)), 0, FALSE));
+ }
+ else
+ {
+ symbol *rlbl = newiTempLabel (NULL);
+ spillPair (PAIR_HL);
+ emit2 ("ld hl,!immed!tlabel", (rlbl->key + 100));
+ emit2 ("push hl");
+ _G.stack.pushed += 2;
+
+ fetchHL (AOP (IC_LEFT (ic)));
+ emit2 ("jp !*hl");
+ emit2 ("!tlabeldef", (rlbl->key + 100));
+ _G.stack.pushed -= 2;
+ }
+ freeAsmop (IC_LEFT (ic), NULL, ic);
+ }
+ else
+ {
+ char *name = OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
+ OP_SYMBOL (IC_LEFT (ic))->rname :
+ OP_SYMBOL (IC_LEFT (ic))->name;
+ if (IS_BANKEDCALL (detype))
+ {
+ emit2 ("call banked_call");
+ emit2 ("!dws", name);
+ emit2 ("!dw !bankimmeds", name);
+ }
+ else
+ {
+ /* make the call */
+ emit2 ("call %s", name);
+ }
+ }
+ spillCached ();
+
+ /* Mark the regsiters as restored. */
+ _G.saves.saved = FALSE;
+
+ /* if we need assign a result value */
+ if ((IS_ITEMP (IC_RESULT (ic)) &&
+ (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+ OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
+ IS_TRUE_SYMOP (IC_RESULT (ic)))
+ {
+
+ aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+
+ assignResultValue (IC_RESULT (ic));
+
+ freeAsmop (IC_RESULT (ic), NULL, ic);
+ }
+
+ /* adjust the stack for parameters if required */
+ if (ic->parmBytes)
+ {
+ int i = ic->parmBytes;
+
+ _G.stack.pushed -= i;
+ if (IS_GB)
+ {
+ emit2 ("!ldaspsp", i);
+ }
+ else
+ {
+ spillCached ();
+ if (i > 6)
+ {
+ emit2 ("ld hl,#%d", i);
+ emit2 ("add hl,sp");
+ emit2 ("ld sp,hl");
+ }
+ else
+ {
+ while (i > 1)
+ {
+ emit2 ("pop hl");
+ i -= 2;
+ }
+ if (i)
+ emit2 ("inc sp");