@@ -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>;
@@ -1399,16 +1411,43 @@ def : Pat<(brind GPR:$rj), (PseudoBRIND GPR:$rj, 0)>;
1399
1411
def : Pat<(brind (add GPR:$rj, simm16_lsl2:$imm16)),
1400
1412
(PseudoBRIND GPR:$rj, simm16_lsl2:$imm16)>;
1401
1413
1414
+ // Function call with 'Small' code model.
1402
1415
let isCall = 1, Defs = [R1] in
1403
1416
def PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func)>;
1404
1417
1405
1418
def : Pat<(loongarch_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>;
1406
1419
def : Pat<(loongarch_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
1407
1420
1421
+ // Function call with 'Medium' code model.
1422
+ let isCall = 1, Defs = [R1, R20], Size = 8 in
1423
+ def PseudoCALL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$func)>;
1424
+
1425
+ let Predicates = [IsLA64] in {
1426
+ def : Pat<(loongarch_call_medium tglobaladdr:$func),
1427
+ (PseudoCALL_MEDIUM tglobaladdr:$func)>;
1428
+ def : Pat<(loongarch_call_medium texternalsym:$func),
1429
+ (PseudoCALL_MEDIUM texternalsym:$func)>;
1430
+ } // Predicates = [IsLA64]
1431
+
1432
+ // Function call with 'Large' code model.
1433
+ let isCall = 1, Defs = [R1, R20], Size = 24 in
1434
+ def PseudoCALL_LARGE: Pseudo<(outs), (ins bare_symbol:$func)>;
1435
+
1436
+ let Predicates = [IsLA64] in {
1437
+ def : Pat<(loongarch_call_large tglobaladdr:$func),
1438
+ (PseudoCALL_LARGE tglobaladdr:$func)>;
1439
+ def : Pat<(loongarch_call_large texternalsym:$func),
1440
+ (PseudoCALL_LARGE texternalsym:$func)>;
1441
+ } // Predicates = [IsLA64]
1442
+
1408
1443
let isCall = 1, Defs = [R1] in
1409
1444
def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rj),
1410
1445
[(loongarch_call GPR:$rj)]>,
1411
1446
PseudoInstExpansion<(JIRL R1, GPR:$rj, 0)>;
1447
+ let Predicates = [IsLA64] in {
1448
+ def : Pat<(loongarch_call_medium GPR:$rj), (PseudoCALLIndirect GPR:$rj)>;
1449
+ def : Pat<(loongarch_call_large GPR:$rj), (PseudoCALLIndirect GPR:$rj)>;
1450
+ }
1412
1451
1413
1452
let isCall = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0, Defs = [R1] in
1414
1453
def PseudoJIRL_CALL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>,
@@ -1419,6 +1458,7 @@ let isBarrier = 1, isReturn = 1, isTerminator = 1 in
1419
1458
def PseudoRET : Pseudo<(outs), (ins), [(loongarch_ret)]>,
1420
1459
PseudoInstExpansion<(JIRL R0, R1, 0)>;
1421
1460
1461
+ // Tail call with 'Small' code model.
1422
1462
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in
1423
1463
def PseudoTAIL : Pseudo<(outs), (ins bare_symbol:$dst)>;
1424
1464
@@ -1427,10 +1467,38 @@ def : Pat<(loongarch_tail (iPTR tglobaladdr:$dst)),
1427
1467
def : Pat<(loongarch_tail (iPTR texternalsym:$dst)),
1428
1468
(PseudoTAIL texternalsym:$dst)>;
1429
1469
1470
+ // Tail call with 'Medium' code model.
1471
+ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
1472
+ Uses = [R3], Defs = [R20], Size = 8 in
1473
+ def PseudoTAIL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$dst)>;
1474
+
1475
+ let Predicates = [IsLA64] in {
1476
+ def : Pat<(loongarch_tail_medium (iPTR tglobaladdr:$dst)),
1477
+ (PseudoTAIL_MEDIUM tglobaladdr:$dst)>;
1478
+ def : Pat<(loongarch_tail_medium (iPTR texternalsym:$dst)),
1479
+ (PseudoTAIL_MEDIUM texternalsym:$dst)>;
1480
+ } // Predicates = [IsLA64]
1481
+
1482
+ // Tail call with 'Large' code model.
1483
+ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
1484
+ Uses = [R3], Defs = [R19, R20], Size = 24 in
1485
+ def PseudoTAIL_LARGE : Pseudo<(outs), (ins bare_symbol:$dst)>;
1486
+
1487
+ let Predicates = [IsLA64] in {
1488
+ def : Pat<(loongarch_tail_large (iPTR tglobaladdr:$dst)),
1489
+ (PseudoTAIL_LARGE tglobaladdr:$dst)>;
1490
+ def : Pat<(loongarch_tail_large (iPTR texternalsym:$dst)),
1491
+ (PseudoTAIL_LARGE texternalsym:$dst)>;
1492
+ } // Predicates = [IsLA64]
1493
+
1430
1494
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in
1431
1495
def PseudoTAILIndirect : Pseudo<(outs), (ins GPRT:$rj),
1432
1496
[(loongarch_tail GPRT:$rj)]>,
1433
1497
PseudoInstExpansion<(JIRL R0, GPR:$rj, 0)>;
1498
+ let Predicates = [IsLA64] in {
1499
+ def : Pat<(loongarch_tail_medium GPR:$rj), (PseudoTAILIndirect GPR:$rj)>;
1500
+ def : Pat<(loongarch_tail_large GPR:$rj), (PseudoTAILIndirect GPR:$rj)>;
1501
+ }
1434
1502
1435
1503
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
1436
1504
hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in
@@ -1468,6 +1536,7 @@ def PseudoLA_ABS_LARGE : Pseudo<(outs GPR:$dst),
1468
1536
"la.abs", "$dst, $src">;
1469
1537
def PseudoLA_PCREL : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1470
1538
"la.pcrel", "$dst, $src">;
1539
+ let Defs = [R20], Size = 20 in
1471
1540
def PseudoLA_PCREL_LARGE : Pseudo<(outs GPR:$dst),
1472
1541
(ins GPR:$tmp, bare_symbol:$src), [],
1473
1542
"la.pcrel", "$dst, $tmp, $src">,
@@ -1479,28 +1548,30 @@ let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
1479
1548
isAsmParserOnly = 1 in {
1480
1549
def PseudoLA_GOT : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1481
1550
"la.got", "$dst, $src">;
1551
+ def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1552
+ "la.tls.ie", "$dst, $src">;
1553
+ def PseudoLA_TLS_LD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1554
+ "la.tls.ld", "$dst, $src">;
1555
+ def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1556
+ "la.tls.gd", "$dst, $src">;
1557
+ let Defs = [R20], Size = 20 in {
1482
1558
def PseudoLA_GOT_LARGE : Pseudo<(outs GPR:$dst),
1483
1559
(ins GPR:$tmp, bare_symbol:$src), [],
1484
1560
"la.got", "$dst, $tmp, $src">,
1485
1561
Requires<[IsLA64]>;
1486
- def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1487
- "la.tls.ie", "$dst, $src">;
1488
1562
def PseudoLA_TLS_IE_LARGE : Pseudo<(outs GPR:$dst),
1489
1563
(ins GPR:$tmp, bare_symbol:$src), [],
1490
1564
"la.tls.ie", "$dst, $tmp, $src">,
1491
1565
Requires<[IsLA64]>;
1492
- def PseudoLA_TLS_LD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1493
- "la.tls.ld", "$dst, $src">;
1494
1566
def PseudoLA_TLS_LD_LARGE : Pseudo<(outs GPR:$dst),
1495
1567
(ins GPR:$tmp, bare_symbol:$src), [],
1496
1568
"la.tls.ld", "$dst, $tmp, $src">,
1497
1569
Requires<[IsLA64]>;
1498
- def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1499
- "la.tls.gd", "$dst, $src">;
1500
1570
def PseudoLA_TLS_GD_LARGE : Pseudo<(outs GPR:$dst),
1501
1571
(ins GPR:$tmp, bare_symbol:$src), [],
1502
1572
"la.tls.gd", "$dst, $tmp, $src">,
1503
1573
Requires<[IsLA64]>;
1574
+ } // Defs = [R20], Size = 20
1504
1575
}
1505
1576
1506
1577
// Load address inst alias: "la", "la.global" and "la.local".
0 commit comments