xref: /aosp_15_r20/external/mesa3d/src/asahi/compiler/agx_lower_64bit.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2022 Alyssa Rosenzweig
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "agx_builder.h"
7 #include "agx_compiler.h"
8 
9 /*
10  * Lower 64-bit moves to 32-bit moves. Although there are not 64-bit moves in
11  * the ISA, it is convenient to pretend there are for instruction selection.
12  * They are lowered trivially after register allocation.
13  *
14  * General 64-bit lowering happens in nir_lower_int64.
15  */
16 static bool
lower(agx_builder * b,agx_instr * I)17 lower(agx_builder *b, agx_instr *I)
18 {
19    if (I->op != AGX_OPCODE_MOV && I->op != AGX_OPCODE_MOV_IMM)
20       return false;
21 
22    if (I->dest[0].size != AGX_SIZE_64)
23       return false;
24 
25    agx_index dest = I->dest[0];
26    dest.size = AGX_SIZE_32;
27 
28    if (I->op == AGX_OPCODE_MOV) {
29       assert(I->src[0].type == AGX_INDEX_REGISTER ||
30              I->src[0].type == AGX_INDEX_UNIFORM);
31       assert(I->src[0].size == AGX_SIZE_64);
32       agx_index src = I->src[0];
33       src.size = AGX_SIZE_32;
34 
35       /* Low 32-bit */
36       agx_mov_to(b, dest, src);
37 
38       /* High 32-bits */
39       dest.value += 2;
40       src.value += 2;
41       agx_mov_to(b, dest, src);
42    } else {
43       /* Low 32-bit */
44       agx_mov_imm_to(b, dest, I->imm & BITFIELD_MASK(32));
45 
46       /* High 32-bits */
47       dest.value += 2;
48       agx_mov_imm_to(b, dest, I->imm >> 32);
49    }
50 
51    return true;
52 }
53 
54 void
agx_lower_64bit_postra(agx_context * ctx)55 agx_lower_64bit_postra(agx_context *ctx)
56 {
57    agx_foreach_instr_global_safe(ctx, I) {
58       agx_builder b = agx_init_builder(ctx, agx_before_instr(I));
59 
60       if (lower(&b, I))
61          agx_remove_instruction(I);
62    }
63 }
64