@@ -506,6 +506,11 @@ import Anvil._
506
506
507
507
config.memoryAccess match {
508
508
case Anvil .Config .MemoryAccess .Default =>
509
+ if (config.useIP) {
510
+ p = anvil.transformCopyDefaultIp(fresh, p, maxTemps)
511
+ output.add(F , irProcedurePath(p.id, p.tipe, stage, pass, " copy" ), p.prettyST(anvil.printer))
512
+ pass = pass + 1
513
+ }
509
514
case Anvil .Config .MemoryAccess .Subroutine =>
510
515
511
516
p = anvil.transformTempLoadSubroutine(fresh, p, maxTemps)
@@ -1285,6 +1290,58 @@ import Anvil._
1285
1290
return p(body = body(blocks = blocks))
1286
1291
}
1287
1292
1293
+ def transformCopyDefaultIp (fresh : lang.IRTranslator .Fresh , p : AST .IR .Procedure , maxTemps : TempVector ): AST .IR .Procedure = {
1294
+ val spt : AST .Typed = if (config.splitTempSizes) spType else AST .Typed .u64
1295
+ fresh.setTemp(maxTemps.typeCount(this , spt))
1296
+ val lhsOffsetParam = fresh.temp()
1297
+ val rhsOffsetParam = fresh.temp()
1298
+ val rhsElementSizeParam = fresh.temp()
1299
+
1300
+ val body = p.body.asInstanceOf [AST .IR .Body .Basic ]
1301
+ var blocks = ISZ [AST .IR .BasicBlock ]()
1302
+ for (b <- body.blocks) {
1303
+ b.grounds match {
1304
+ case ISZ (AST .IR .Stmt .Intrinsic (in : Intrinsic .Copy )) if ! in.rhsBytes.isInstanceOf [AST .IR .Exp .Int ] =>
1305
+ val copyLabel = fresh.label()
1306
+ val t = in.rhsTipe
1307
+ val pos = in.pos
1308
+ var grounds = ISZ [AST .IR .Stmt .Ground ]()
1309
+ grounds = grounds :+ AST .IR .Stmt .Assign .Temp (lhsOffsetParam, in.lhsOffset, pos)
1310
+ grounds = grounds :+ AST .IR .Stmt .Assign .Temp (rhsOffsetParam, in.rhs, pos)
1311
+ val sizeInfoOpt = classSizeFieldOffsets(t.asInstanceOf [AST .Typed .Name ])._2.get(" size" )
1312
+ if (config.erase || sizeInfoOpt.isEmpty) {
1313
+ grounds = grounds :+ AST .IR .Stmt .Assign .Temp (rhsElementSizeParam, in.rhsBytes, pos)
1314
+ } else {
1315
+ val (sizeType, sizeOffset) = sizeInfoOpt.get
1316
+ val elementByteSize : Z = if (t == AST .Typed .string) 1 else typeByteSize(t.asInstanceOf [AST .Typed .Name ].args(1 ))
1317
+ var elementSize : AST .IR .Exp = AST .IR .Exp .Type (F ,
1318
+ AST .IR .Exp .Intrinsic (Intrinsic .Load (
1319
+ AST .IR .Exp .Binary (spType, in.rhs, AST .IR .Exp .Binary .Op .Add , AST .IR .Exp .Int (spType, sizeOffset, pos), pos),
1320
+ isSigned(sizeType), typeByteSize(sizeType), st " " , sizeType, pos)),
1321
+ spType, pos)
1322
+ if (elementByteSize != 1 ) {
1323
+ elementSize = AST .IR .Exp .Binary (spType, elementSize, AST .IR .Exp .Binary .Op .Mul ,
1324
+ AST .IR .Exp .Int (spType, elementByteSize, pos), pos)
1325
+ }
1326
+ grounds = grounds :+ AST .IR .Stmt .Assign .Temp (rhsElementSizeParam, elementSize, pos)
1327
+ }
1328
+ blocks = blocks :+ AST .IR .BasicBlock (b.label, grounds, AST .IR .Jump .Goto (copyLabel, pos))
1329
+ blocks = blocks :+ AST .IR .BasicBlock (copyLabel, ISZ (
1330
+ AST .IR .Stmt .Intrinsic (in(
1331
+ lhsOffset = AST .IR .Exp .Temp (lhsOffsetParam, spType, pos),
1332
+ rhs = AST .IR .Exp .Temp (rhsOffsetParam, spType, pos),
1333
+ rhsBytes =
1334
+ if (config.erase) AST .IR .Exp .Temp (rhsElementSizeParam, spType, pos)
1335
+ else AST .IR .Exp .Binary (spType,
1336
+ AST .IR .Exp .Temp (rhsElementSizeParam, spType, pos), AST .IR .Exp .Binary .Op .Add ,
1337
+ AST .IR .Exp .Int (spType, typeShaSize + typeByteSize(AST .Typed .z), pos), pos)))
1338
+ ), b.jump)
1339
+ case _ => blocks = blocks :+ b
1340
+ }
1341
+ }
1342
+ return p(body = body(blocks = blocks))
1343
+ }
1344
+
1288
1345
def transformCopySubroutine (fresh : lang.IRTranslator .Fresh , p : AST .IR .Procedure , maxTemps : TempVector ): AST .IR .Procedure = {
1289
1346
val copyLabel = fresh.label()
1290
1347
val cpt : AST .Typed = if (config.splitTempSizes) cpType else AST .Typed .u64
0 commit comments