-
- /* if send set is not empty then assign */
- if (sendSet) {
- iCode *sic;
- int send = 0;
- int n = elementsInSet(sendSet);
- if (IS_Z80 && n == 2 && _isPairUsed(ic, PAIR_DE)) {
- /* Only push de if it is used and if it's not used
- in the return value */
- /* Panic if partly used */
- if (_opUsesPair(IC_RESULT(ic), ic, PAIR_DE) == 1) {
- emit2("; Warning: de crossover");
- }
- else if (!_opUsesPair(IC_RESULT(ic), ic, PAIR_DE)) {
- /* Store away de */
- _push(PAIR_DE);
- pushed_de = 1;
- }
- }
- /* PENDING: HACK */
- if (IS_Z80 && n == 2 ) {
- /* Want to load HL first, then DE as HL may = DE */
- sic = setFirstItem(sendSet);
- sic = setNextItem(sendSet);
- aopOp(IC_LEFT(sic),sic,FALSE, FALSE);
- fetchPair(PAIR_HL, AOP(IC_LEFT(sic)));
- send++;
- freeAsmop (IC_LEFT(sic),NULL,sic);
- sic = setFirstItem(sendSet);
- aopOp(IC_LEFT(sic),sic,FALSE, FALSE);
- fetchPair(PAIR_DE, AOP(IC_LEFT(sic)));
- send++;
- freeAsmop (IC_LEFT(sic),NULL,sic);
- }
- else {
- for (sic = setFirstItem(sendSet) ; sic ;
- sic = setNextItem(sendSet)) {
- int size;
- aopOp(IC_LEFT(sic),sic,FALSE, FALSE);
- size = AOP_SIZE(IC_LEFT(sic));
- wassert(size <= 2);
- /* Always send in pairs */
- switch (send) {
- case 0:
- if (IS_Z80 && n == 1)
- fetchPair(PAIR_HL, AOP(IC_LEFT(sic)));
- else
- fetchPair(PAIR_DE, AOP(IC_LEFT(sic)));
- break;
- case 1:
- fetchPair(PAIR_HL, AOP(IC_LEFT(sic)));
- break;
- default:
- /* Send set too big */
- wassert(0);
- }
- send++;
- freeAsmop (IC_LEFT(sic),NULL,sic);
- }
- }
- sendSet = NULL;
- if (pushed_de) {
- }
+
+ _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;