@@ -1162,40 +1162,28 @@ void getlvalue(ref CodeBuilder cdb,ref code pcs,elem* e,regm_t keepmsk,RM rm = R
11621162// fltregs
11631163
11641164/* ****************************
1165- * Given a result in registers, test it for true or false.
1166- * Will fail if TYfptr and the reg is ES!
1167- * If saveflag is true, preserve the contents of the
1168- * registers.
1165+ * Given a result in registers regm, test it for true or false.
1166+ * Params:
1167+ * cdb = generated code sink
1168+ * regm = result register(s) and mPSW
1169+ * tym = type of result
1170+ * saveflag = true means preserve the contents of the registers
11691171 */
11701172@trusted
11711173void tstresult (ref CodeBuilder cdb, regm_t regm, tym_t tym, bool saveflag)
11721174{
1173- reg_t scrreg; // scratch register
1174- regm_t scrregm;
1175-
1176- // if (!(regm & (mBP | ALLREGS)))
1177- // printf("tstresult(regm = %s, tym = x%x, saveflag = %d)\n",
1178- // regm_str(regm),tym,saveflag);
1175+ // printf("tstresult(regm = %s, tym = x%x, saveflag = %d)\n",regm_str(regm),tym,saveflag);
11791176
11801177 tym = tybasic(tym);
11811178 reg_t reg = findreg(regm);
11821179 uint sz = _tysize[tym];
1183- assert (regm & cgstate.allregs);
1184- static if (0 )
1185- {
1186- assert (regm & (XMMREGS | mBP | ALLREGS ));
1187- if (sz == 1 )
1188- {
1189- assert (regm & BYTEREGS );
1190- genregs(cdb, 0x84 , reg, reg); // TEST regL,regL
1191- if (I64 && reg >= 4 )
1192- code_orrex(cdb.last(), REX );
1193- return ;
1194- }
1180+ assert (regm & (cgstate.allregs | INSTR .FLOATREGS ));
1181+
1182+ static if (0 )
11951183 if (regm & XMMREGS )
11961184 {
11971185 regm_t xregs = XMMREGS & ~ regm;
1198- const xreg = allocreg(cdb,xregs, TYdouble);
1186+ const xreg = allocreg(cdb,xregs,TYdouble);
11991187 opcode_t op = 0 ;
12001188 if (tym == TYdouble || tym == TYidouble || tym == TYcdouble)
12011189 op = 0x660000 ;
@@ -1211,104 +1199,16 @@ static if (0)
12111199 }
12121200 return ;
12131201 }
1214- }
1215- if (sz <= REGSIZE )
1216- {
1217- if (tym == TYfloat)
1218- {
1219- if (saveflag)
1220- {
1221- scrregm = cgstate.allregs & ~ regm; // possible scratch regs
1222- scrreg = allocreg(cdb, scrregm, TYoffset); // allocate scratch reg
1223- genmovreg(cdb, scrreg, reg); // MOV scrreg,msreg
1224- reg = scrreg;
1225- }
1226- getregs(cdb, mask (reg));
1227- cdb.gen2(0xD1 , modregrmx (3 , 4 , reg)); // SHL reg,1
1228- return ;
1229- }
1230- }
1231-
1232- gentstreg(cdb,reg,sz == 8 ); // CMP reg,#0
1233-
12341202
1235- static if (0 )
1236- {
1237- if (saveflag || tyfv(tym))
1203+ if (tyfloating(tym))
12381204 {
1239- L1 :
1240- scrregm = ALLREGS & ~ regm; // possible scratch regs
1241- scrreg = allocreg(cdb, scrregm, TYoffset); // allocate scratch reg
1242- if (I32 || sz == REGSIZE * 2 )
1243- {
1244- assert (regm & mMSW && regm & mLSW);
1245-
1246- reg = findregmsw(regm);
1247- if (I32 )
1248- {
1249- if (tyfv(tym))
1250- genregs(cdb, MOVZXw, scrreg, reg); // MOVZX scrreg,msreg
1251- else
1252- {
1253- genmovreg(cdb, scrreg, reg); // MOV scrreg,msreg
1254- if (tym == TYdouble || tym == TYdouble_alias)
1255- cdb.gen2(0xD1 , modregrm (3 , 4 , scrreg)); // SHL scrreg,1
1256- }
1257- }
1258- else
1259- {
1260- genmovreg(cdb, scrreg, reg); // MOV scrreg,msreg
1261- if (tym == TYfloat)
1262- cdb.gen2(0xD1 , modregrm (3 , 4 , scrreg)); // SHL scrreg,1
1263- }
1264- reg = findreglsw(regm);
1265- genorreg(cdb, scrreg, reg); // OR scrreg,lsreg
1266- }
1267- else if (sz == 8 )
1268- {
1269- // !I32
1270- genmovreg(cdb, scrreg, AX ); // MOV scrreg,AX
1271- if (tym == TYdouble || tym == TYdouble_alias)
1272- cdb.gen2(0xD1 ,modregrm(3 , 4 , scrreg)); // SHL scrreg,1
1273- genorreg(cdb, scrreg, BX ); // OR scrreg,BX
1274- genorreg(cdb, scrreg, CX ); // OR scrreg,CX
1275- genorreg(cdb, scrreg, DX ); // OR scrreg,DX
1276- }
1277- else
1278- assert (0 );
1205+ const ftype = INSTR .szToFtype(sz);
1206+ cdb.gen1(INSTR .fcmp_float(ftype,0 ,reg)); // FCMP Vn,#0.0
12791207 }
12801208 else
1281- {
1282- if (I32 || sz == REGSIZE * 2 )
1283- {
1284- // can't test ES:LSW for 0
1285- assert (regm & mMSW & ALLREGS && regm & (mLSW | mBP));
1286-
1287- reg = findregmsw(regm);
1288- if (cgstate.regcon.mvar & mask(reg)) // if register variable
1289- goto L1 ; // don't trash it
1290- getregs(cdb, mask (reg)); // we're going to trash reg
1291- if (tyfloating(tym) && sz == 2 * _tysize[TYint])
1292- cdb.gen2(0xD1 , modregrm (3 ,4 , reg)); // SHL reg,1
1293- genorreg(cdb, reg, findreglsw(regm)); // OR reg,reg+1
1294- if (I64 )
1295- code_orrex(cdb.last(), REX_W );
1296- }
1297- else if (sz == 8 )
1298- { assert (regm == DOUBLEREGS_16 );
1299- getregs(cdb,mAX); // allocate AX
1300- if (tym == TYdouble || tym == TYdouble_alias)
1301- cdb.gen2(0xD1 , modregrm (3 , 4 , AX )); // SHL AX,1
1302- genorreg(cdb, AX , BX ); // OR AX,BX
1303- genorreg(cdb, AX , CX ); // OR AX,CX
1304- genorreg(cdb, AX , DX ); // OR AX,DX
1305- }
1306- else
1307- assert (0 );
1308- }
1209+ gentstreg(cdb,reg,sz == 8 ); // CMP reg,#0
13091210 code_orflag(cdb.last(),CFpsw);
13101211}
1311- }
13121212
13131213
13141214/* *****************************
@@ -2300,22 +2200,10 @@ static if (1)
23002200 cdrelconst(cgstate,cdb,e,outretregs);
23012201 return ;
23022202 }
2303- if (tyfloating(tym))
2304- {
2305- objmod.fltused();
2306- if (config.fpxmmregs &&
2307- (tym == TYcfloat || tym == TYcdouble) &&
2308- (outretregs & (XMMREGS | mPSW))
2309- )
2310- {
2311- cloadxmm(cdb, e, outretregs);
2312- return ;
2313- }
2314- }
23152203
23162204 if (outretregs == mPSW)
23172205 {
2318- regm_t retregs = cgstate.allregs;
2206+ regm_t retregs = tyfloating(tym) ? INSTR . FLOATREGS : cgstate.allregs;
23192207 loaddata(cdb, e, retregs);
23202208 fixresult(cdb, e, retregs, outretregs);
23212209 return ;
@@ -2326,8 +2214,6 @@ static if (1)
23262214 cs.Iflags = 0 ;
23272215 flags = outretregs & mPSW; /* save original */
23282216 forregs = outretregs & (cgstate.allregs | INSTR .FLOATREGS ); // XMMREGS ?
2329- // if (outretregs & mSTACK)
2330- // forregs |= DOUBLEREGS;
23312217 if (e.Eoper == OPconst)
23322218 {
23332219 if (tyvector(tym) && forregs & XMMREGS )
@@ -2397,7 +2283,7 @@ static if (1)
23972283 const reg_t preg = e.Voffset ? e.Vsym.Spreg2 : e.Vsym.Spreg;
23982284 const regm_t pregm = mask(preg);
23992285
2400- if (! (sz <= 2 && pregm & XMMREGS )) // no SIMD instructions to load 1 or 2 byte quantities
2286+ // if (!(sz <= 2 && pregm & XMMREGS)) // no SIMD instructions to load 1 or 2 byte quantities
24012287 {
24022288 if (debugr)
24032289 printf(" %s.%d is fastpar and using register %s\n " ,
@@ -2458,7 +2344,7 @@ static if (1)
24582344 }
24592345 }
24602346 }
2461- else if (forregs & XMMREGS )
2347+ else if (0 && forregs & XMMREGS )
24622348 {
24632349 // Can't load from registers directly to XMM regs
24642350 // e.Vsym.Sflags &= ~GTregcand;
@@ -2477,10 +2363,18 @@ static if (1)
24772363 }
24782364 else if (sz <= REGSIZE )
24792365 {
2480- // LDR reg,[sp,#offset]
2481- // https://www.scs.stanford.edu/~zyedidia/arm64/ldr_imm_gen.html
2482- opcode_t opmv = PSOP .ldr | (29 << 5 );
2483- loadea(cdb, e, cs, opmv, reg, 0 , 0 , 0 , RM .load);
2366+ if (tyfloating(tym))
2367+ {
2368+ loadea(cdb,e,cs,0 ,reg,0 ,0 ,0 ,RM .load);
2369+ outretregs = mask(reg);
2370+ }
2371+ else
2372+ {
2373+ // LDR reg,[sp,#offset]
2374+ // https://www.scs.stanford.edu/~zyedidia/arm64/ldr_imm_gen.html
2375+ opcode_t opmv = PSOP .ldr | (29 << 5 );
2376+ loadea(cdb, e, cs, opmv, reg, 0 , 0 , 0 , RM .load);
2377+ }
24842378 }
24852379 else if (sz <= 2 * REGSIZE )
24862380 {
@@ -2515,6 +2409,7 @@ static if (1)
25152409 assert (0 );
25162410 // Flags may already be set
25172411 outretregs &= flags | ~ mPSW;
2412+ // printf("outretregs: %llx\n", outretregs);
25182413 fixresult(cdb, e, forregs, outretregs);
25192414 return ;
25202415 }
0 commit comments