@@ -69,6 +69,18 @@ def loongarch_ret : SDNode<"LoongArchISD::RET", SDTNone,
69
69
def loongarch_tail : SDNode<"LoongArchISD::TAIL", SDT_LoongArchCall,
70
70
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
71
71
SDNPVariadic]>;
72
+ def loongarch_call_medium : SDNode<"LoongArchISD::CALL_MEDIUM", SDT_LoongArchCall,
73
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
74
+ SDNPVariadic]>;
75
+ def loongarch_tail_medium : SDNode<"LoongArchISD::TAIL_MEDIUM", SDT_LoongArchCall,
76
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
77
+ SDNPVariadic]>;
78
+ def loongarch_call_large : SDNode<"LoongArchISD::CALL_LARGE", SDT_LoongArchCall,
79
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
80
+ SDNPVariadic]>;
81
+ def loongarch_tail_large : SDNode<"LoongArchISD::TAIL_LARGE", SDT_LoongArchCall,
82
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
83
+ SDNPVariadic]>;
72
84
def loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>;
73
85
def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>;
74
86
def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>;
@@ -1327,16 +1339,43 @@ def : Pat<(brind GPR:$rj), (PseudoBRIND GPR:$rj, 0)>;
1327
1339
def : Pat<(brind (add GPR:$rj, simm16_lsl2:$imm16)),
1328
1340
(PseudoBRIND GPR:$rj, simm16_lsl2:$imm16)>;
1329
1341
1342
+ // Function call with 'Small' code model.
1330
1343
let isCall = 1, Defs = [R1] in
1331
1344
def PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func)>;
1332
1345
1333
1346
def : Pat<(loongarch_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>;
1334
1347
def : Pat<(loongarch_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
1335
1348
1349
+ // Function call with 'Medium' code model.
1350
+ let isCall = 1, Defs = [R1, R20], Size = 8 in
1351
+ def PseudoCALL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$func)>;
1352
+
1353
+ let Predicates = [IsLA64] in {
1354
+ def : Pat<(loongarch_call_medium tglobaladdr:$func),
1355
+ (PseudoCALL_MEDIUM tglobaladdr:$func)>;
1356
+ def : Pat<(loongarch_call_medium texternalsym:$func),
1357
+ (PseudoCALL_MEDIUM texternalsym:$func)>;
1358
+ } // Predicates = [IsLA64]
1359
+
1360
+ // Function call with 'Large' code model.
1361
+ let isCall = 1, Defs = [R1, R20], Size = 24 in
1362
+ def PseudoCALL_LARGE: Pseudo<(outs), (ins bare_symbol:$func)>;
1363
+
1364
+ let Predicates = [IsLA64] in {
1365
+ def : Pat<(loongarch_call_large tglobaladdr:$func),
1366
+ (PseudoCALL_LARGE tglobaladdr:$func)>;
1367
+ def : Pat<(loongarch_call_large texternalsym:$func),
1368
+ (PseudoCALL_LARGE texternalsym:$func)>;
1369
+ } // Predicates = [IsLA64]
1370
+
1336
1371
let isCall = 1, Defs = [R1] in
1337
1372
def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rj),
1338
1373
[(loongarch_call GPR:$rj)]>,
1339
1374
PseudoInstExpansion<(JIRL R1, GPR:$rj, 0)>;
1375
+ let Predicates = [IsLA64] in {
1376
+ def : Pat<(loongarch_call_medium GPR:$rj), (PseudoCALLIndirect GPR:$rj)>;
1377
+ def : Pat<(loongarch_call_large GPR:$rj), (PseudoCALLIndirect GPR:$rj)>;
1378
+ }
1340
1379
1341
1380
let isCall = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0, Defs = [R1] in
1342
1381
def PseudoJIRL_CALL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>,
@@ -1347,6 +1386,7 @@ let isBarrier = 1, isReturn = 1, isTerminator = 1 in
1347
1386
def PseudoRET : Pseudo<(outs), (ins), [(loongarch_ret)]>,
1348
1387
PseudoInstExpansion<(JIRL R0, R1, 0)>;
1349
1388
1389
+ // Tail call with 'Small' code model.
1350
1390
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in
1351
1391
def PseudoTAIL : Pseudo<(outs), (ins bare_symbol:$dst)>;
1352
1392
@@ -1355,10 +1395,38 @@ def : Pat<(loongarch_tail (iPTR tglobaladdr:$dst)),
1355
1395
def : Pat<(loongarch_tail (iPTR texternalsym:$dst)),
1356
1396
(PseudoTAIL texternalsym:$dst)>;
1357
1397
1398
+ // Tail call with 'Medium' code model.
1399
+ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
1400
+ Uses = [R3], Defs = [R20], Size = 8 in
1401
+ def PseudoTAIL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$dst)>;
1402
+
1403
+ let Predicates = [IsLA64] in {
1404
+ def : Pat<(loongarch_tail_medium (iPTR tglobaladdr:$dst)),
1405
+ (PseudoTAIL_MEDIUM tglobaladdr:$dst)>;
1406
+ def : Pat<(loongarch_tail_medium (iPTR texternalsym:$dst)),
1407
+ (PseudoTAIL_MEDIUM texternalsym:$dst)>;
1408
+ } // Predicates = [IsLA64]
1409
+
1410
+ // Tail call with 'Large' code model.
1411
+ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
1412
+ Uses = [R3], Defs = [R19, R20], Size = 24 in
1413
+ def PseudoTAIL_LARGE : Pseudo<(outs), (ins bare_symbol:$dst)>;
1414
+
1415
+ let Predicates = [IsLA64] in {
1416
+ def : Pat<(loongarch_tail_large (iPTR tglobaladdr:$dst)),
1417
+ (PseudoTAIL_LARGE tglobaladdr:$dst)>;
1418
+ def : Pat<(loongarch_tail_large (iPTR texternalsym:$dst)),
1419
+ (PseudoTAIL_LARGE texternalsym:$dst)>;
1420
+ } // Predicates = [IsLA64]
1421
+
1358
1422
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in
1359
1423
def PseudoTAILIndirect : Pseudo<(outs), (ins GPRT:$rj),
1360
1424
[(loongarch_tail GPRT:$rj)]>,
1361
1425
PseudoInstExpansion<(JIRL R0, GPR:$rj, 0)>;
1426
+ let Predicates = [IsLA64] in {
1427
+ def : Pat<(loongarch_tail_medium GPR:$rj), (PseudoTAILIndirect GPR:$rj)>;
1428
+ def : Pat<(loongarch_tail_large GPR:$rj), (PseudoTAILIndirect GPR:$rj)>;
1429
+ }
1362
1430
1363
1431
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
1364
1432
hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in
@@ -1396,6 +1464,7 @@ def PseudoLA_ABS_LARGE : Pseudo<(outs GPR:$dst),
1396
1464
"la.abs", "$dst, $src">;
1397
1465
def PseudoLA_PCREL : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1398
1466
"la.pcrel", "$dst, $src">;
1467
+ let Defs = [R20], Size = 20 in
1399
1468
def PseudoLA_PCREL_LARGE : Pseudo<(outs GPR:$dst),
1400
1469
(ins GPR:$tmp, bare_symbol:$src), [],
1401
1470
"la.pcrel", "$dst, $tmp, $src">,
@@ -1407,28 +1476,30 @@ let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
1407
1476
isAsmParserOnly = 1 in {
1408
1477
def PseudoLA_GOT : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1409
1478
"la.got", "$dst, $src">;
1479
+ def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1480
+ "la.tls.ie", "$dst, $src">;
1481
+ def PseudoLA_TLS_LD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1482
+ "la.tls.ld", "$dst, $src">;
1483
+ def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1484
+ "la.tls.gd", "$dst, $src">;
1485
+ let Defs = [R20], Size = 20 in {
1410
1486
def PseudoLA_GOT_LARGE : Pseudo<(outs GPR:$dst),
1411
1487
(ins GPR:$tmp, bare_symbol:$src), [],
1412
1488
"la.got", "$dst, $tmp, $src">,
1413
1489
Requires<[IsLA64]>;
1414
- def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1415
- "la.tls.ie", "$dst, $src">;
1416
1490
def PseudoLA_TLS_IE_LARGE : Pseudo<(outs GPR:$dst),
1417
1491
(ins GPR:$tmp, bare_symbol:$src), [],
1418
1492
"la.tls.ie", "$dst, $tmp, $src">,
1419
1493
Requires<[IsLA64]>;
1420
- def PseudoLA_TLS_LD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1421
- "la.tls.ld", "$dst, $src">;
1422
1494
def PseudoLA_TLS_LD_LARGE : Pseudo<(outs GPR:$dst),
1423
1495
(ins GPR:$tmp, bare_symbol:$src), [],
1424
1496
"la.tls.ld", "$dst, $tmp, $src">,
1425
1497
Requires<[IsLA64]>;
1426
- def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1427
- "la.tls.gd", "$dst, $src">;
1428
1498
def PseudoLA_TLS_GD_LARGE : Pseudo<(outs GPR:$dst),
1429
1499
(ins GPR:$tmp, bare_symbol:$src), [],
1430
1500
"la.tls.gd", "$dst, $tmp, $src">,
1431
1501
Requires<[IsLA64]>;
1502
+ } // Defs = [R20], Size = 20
1432
1503
}
1433
1504
1434
1505
// Load address inst alias: "la", "la.global" and "la.local".
0 commit comments