Skip to content

Commit e8dbbd2

Browse files
authored
implement REGSAVE_save/restor for floating point registers (dlang#21307)
1 parent 122de2a commit e8dbbd2

1 file changed

Lines changed: 30 additions & 14 deletions

File tree

  • compiler/src/dmd/backend/arm

compiler/src/dmd/backend/arm/cod3.d

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ nothrow:
6969
void REGSAVE_save(ref REGSAVE regsave, ref CodeBuilder cdb, reg_t reg, out uint idx)
7070
{
7171
//printf("REGSAVE_save() %s\n", regm_str(mask(reg)));
72-
assert(reg < 32); // TODO AArch64 floating point registers
72+
// TODO AArch64 do 128 bit registers
7373
if (!regsave.alignment)
7474
regsave.alignment = REGSIZE;
7575
idx = regsave.idx;
@@ -81,7 +81,17 @@ void REGSAVE_save(ref REGSAVE regsave, ref CodeBuilder cdb, reg_t reg, out uint
8181
cs.base = cgstate.BP;
8282
cs.index = NOREG;
8383
cs.IFL1 = FL.regsave;
84-
cs.Iop = INSTR.str_imm_gen(1,reg,cs.base,idx);
84+
if (mask(reg) & INSTR.FLOATREGS)
85+
{
86+
uint imm12 = idx;
87+
uint sz = 8;
88+
uint size, opc;
89+
INSTR.szToSizeOpc(sz, size, opc);
90+
imm12 /= sz;
91+
cs.Iop = INSTR.str_imm_fpsimd(size,opc,imm12,cs.base,reg);
92+
}
93+
else
94+
cs.Iop = INSTR.str_imm_gen(1,reg,cs.base,idx);
8595
cdb.gen(&cs);
8696

8797
cgstate.reflocal = true;
@@ -98,14 +108,23 @@ void REGSAVE_save(ref REGSAVE regsave, ref CodeBuilder cdb, reg_t reg, out uint
98108
void REGSAVE_restore(const ref REGSAVE regsave, ref CodeBuilder cdb, reg_t reg, uint idx)
99109
{
100110
//printf("REGSAVE_restore() %s\n", regm_str(mask(reg)));
101-
assert(reg < 32); // TODO AArch64 floating point registers
102111
// LDR reg,[BP, #idx]
103112
code cs;
104113
cs.reg = reg;
105114
cs.base = cgstate.BP;
106115
cs.index = NOREG;
107116
cs.IFL1 = FL.regsave;
108-
cs.Iop = INSTR.ldr_imm_gen(1,reg,cs.base,idx);
117+
if (mask(reg) & INSTR.FLOATREGS)
118+
{
119+
uint imm12 = idx;
120+
uint sz = 8;
121+
uint size, opc;
122+
INSTR.szToSizeOpc(sz, size, opc);
123+
imm12 /= sz;
124+
cs.Iop = INSTR.ldr_imm_fpsimd(size,opc,imm12,cs.base,reg);
125+
}
126+
else
127+
cs.Iop = INSTR.ldr_imm_gen(1,reg,cs.base,idx);
109128
cdb.gen(&cs);
110129
}
111130

@@ -1064,20 +1083,17 @@ L3:
10641083
@trusted
10651084
void genmovreg(ref CodeBuilder cdb, reg_t to, reg_t from, tym_t ty = TYMAX)
10661085
{
1067-
// TODO ftype and TYMAX ?
1068-
if (to <= 31)
1086+
if (to & INSTR.FLOATREGS)
10691087
{
1070-
// integer
1071-
uint sf = ty == TYMAX || _tysize[ty] == 8;
1072-
cdb.gen1(INSTR.mov_register(sf, from, to));
1088+
// floating point
1089+
uint ftype = INSTR.szToFtype(ty == TYMAX ? 8 : _tysize[ty]);
1090+
cdb.gen1(INSTR.fmov(ftype, from & 31, to & 31));
10731091
}
10741092
else
10751093
{
1076-
// floating point
1077-
uint ftype = (ty == TYMAX || _tysize[ty] == 8)
1078-
? 1
1079-
: (_tysize[ty] == 4 ? 0 : 3);
1080-
cdb.gen1(INSTR.fmov(ftype, from & 31, to & 31));
1094+
// integer
1095+
uint sf = ty == TYMAX || _tysize[ty] == 8;
1096+
cdb.gen1(INSTR.mov_register(sf, from, to));
10811097
}
10821098
}
10831099

0 commit comments

Comments
 (0)