@@ -231,6 +231,8 @@ public Optional<vadl.viam.Definition> visit(ApplicationBinaryInterfaceDefinition
231231 var id = generateIdentifier (definition .viamId , definition .identifier ());
232232 var aliasLookup = aliasLookupTable (definition .definitions );
233233
234+ // Special Registers
235+
234236 var stackPointerDef = getSpecialPurposeRegisterDefinition (definition .definitions ,
235237 SpecialPurposeRegisterDefinition .Purpose .STACK_POINTER );
236238 var returnAddressDef =
@@ -240,14 +242,31 @@ public Optional<vadl.viam.Definition> visit(ApplicationBinaryInterfaceDefinition
240242 SpecialPurposeRegisterDefinition .Purpose .GLOBAL_POINTER );
241243 var framePtrDef = getSpecialPurposeRegisterDefinition (definition .definitions ,
242244 SpecialPurposeRegisterDefinition .Purpose .FRAME_POINTER );
243- var threadPtrDef = getSpecialPurposeRegisterDefinition (definition .definitions ,
244- SpecialPurposeRegisterDefinition .Purpose .THREAD_POINTER );
245-
246- var stackPointer = mapToRegisterRef (aliasLookup , stackPointerDef );
247- var returnAddress = mapToRegisterRef (aliasLookup , returnAddressDef );
248- var globalPtr = mapToRegisterRef (aliasLookup , globalPtrDef );
249- var framePtr = mapToRegisterRef (aliasLookup , framePtrDef );
250- var threadPtr = mapToRegisterRef (aliasLookup , threadPtrDef );
245+ var threadPtr = getOptionalSpecialPurposeRegisterDefinition (definition .definitions ,
246+ SpecialPurposeRegisterDefinition .Purpose .THREAD_POINTER )
247+ .map (def -> mapSingleSpecialPurposeRegisterDef (aliasLookup , def ));
248+
249+ var stackPointer = mapSingleSpecialPurposeRegisterDef (aliasLookup , stackPointerDef );
250+ var returnAddress = mapSingleSpecialPurposeRegisterDef (aliasLookup , returnAddressDef );
251+ var globalPtr = mapSingleSpecialPurposeRegisterDef (aliasLookup , globalPtrDef );
252+ var framePtr = mapSingleSpecialPurposeRegisterDef (aliasLookup , framePtrDef );
253+
254+ // Calling Convention
255+ var returnValueDef = getSpecialPurposeRegisterDefinition (definition .definitions ,
256+ SpecialPurposeRegisterDefinition .Purpose .RETURN_VALUE );
257+ var functionArgumentDef = getSpecialPurposeRegisterDefinition (definition .definitions ,
258+ SpecialPurposeRegisterDefinition .Purpose .FUNCTION_ARGUMENT );
259+ var callerSavedDef = getSpecialPurposeRegisterDefinition (definition .definitions ,
260+ SpecialPurposeRegisterDefinition .Purpose .CALLER_SAVED );
261+ var calleeSavedDef = getSpecialPurposeRegisterDefinition (definition .definitions ,
262+ SpecialPurposeRegisterDefinition .Purpose .CALLEE_SAVED );
263+
264+ var returnValues = mapSpecialPurposeRegistersDef (aliasLookup , returnValueDef );
265+ var functionArguments = mapSpecialPurposeRegistersDef (aliasLookup , functionArgumentDef );
266+ var callerSaved = mapSpecialPurposeRegistersDef (aliasLookup , callerSavedDef );
267+ var calleeSaved = mapSpecialPurposeRegistersDef (aliasLookup , calleeSavedDef );
268+
269+ // Pseudo Instructions
251270
252271 var pseudoRetInstrDef = getAbiPseudoInstruction (definition .definitions ,
253272 AbiPseudoInstructionDefinition .Kind .RETURN );
@@ -260,6 +279,8 @@ public Optional<vadl.viam.Definition> visit(ApplicationBinaryInterfaceDefinition
260279 var pseudoCall = (PseudoInstruction ) fetch (pseudoCallInstrDef ).orElseThrow ();
261280 var pseudoLocalAddressLoad = (PseudoInstruction ) fetch (pseudoLocalAddressLoadDef ).orElseThrow ();
262281
282+ // Aliases
283+
263284 Map <Pair <RegisterFile , Integer >, List <Abi .RegisterAlias >> aliases =
264285 aliasLookup .entrySet ()
265286 .stream ()
@@ -293,10 +314,10 @@ public Optional<vadl.viam.Definition> visit(ApplicationBinaryInterfaceDefinition
293314 globalPtr ,
294315 threadPtr ,
295316 aliases ,
296- Collections . emptyList () ,
297- Collections . emptyList () ,
298- Collections . emptyList () ,
299- Collections . emptyList () ,
317+ callerSaved ,
318+ calleeSaved ,
319+ functionArguments ,
320+ returnValues ,
300321 pseudoRet ,
301322 pseudoCall ,
302323 pseudoLocalAddressLoad ,
@@ -1257,16 +1278,39 @@ public Optional<vadl.viam.Definition> visit(
12571278 return Optional .ofNullable (pseudoInstructionDefinition ).flatMap (this ::fetch );
12581279 }
12591280
1281+ /**
1282+ * Maps a {@link SpecialPurposeRegisterDefinition} to a {@link Abi.RegisterRef}.
1283+ * It expects only one register in the {@link SpecialPurposeRegisterDefinition}. Otherwise,
1284+ * it will throw an error.
1285+ */
1286+ private Abi .RegisterRef mapSingleSpecialPurposeRegisterDef (
1287+ Map <Identifier , Expr > aliasLookup ,
1288+ SpecialPurposeRegisterDefinition specialPurposeRegisterDef ) {
1289+ var identifier = specialPurposeRegisterDef .exprs .stream ().findFirst ().orElseThrow ().target ;
1290+ return mapToRegisterRef (aliasLookup , identifier );
1291+ }
1292+
1293+ /**
1294+ * Maps a {@link SpecialPurposeRegisterDefinition} to a list of {@link Abi.RegisterRef}.
1295+ */
1296+ private List <Abi .RegisterRef > mapSpecialPurposeRegistersDef (
1297+ Map <Identifier , Expr > aliasLookup ,
1298+ SpecialPurposeRegisterDefinition specialPurposeRegisterDef ) {
1299+ return specialPurposeRegisterDef .exprs .stream ()
1300+ .map (x -> mapToRegisterRef (aliasLookup , x .target ))
1301+ .toList ();
1302+ }
1303+
12601304 /**
12611305 * Maps the aliases {@code alias register zero = X(0)} to {@link Abi.RegisterRef} to be
12621306 * used in {@link Abi}.
12631307 */
12641308 private Abi .RegisterRef mapToRegisterRef (
12651309 Map <Identifier , Expr > aliasLookup ,
1266- SpecialPurposeRegisterDefinition specialPurposeRegisterDef ) {
1267- var expr = ensureNonNull (aliasLookup .get (specialPurposeRegisterDef . aliasName ),
1310+ Identifier identifier ) {
1311+ var expr = ensureNonNull (aliasLookup .get (identifier ),
12681312 () -> Diagnostic .error ("Cannot alias for register definition" ,
1269- specialPurposeRegisterDef . aliasName .sourceLocation ()));
1313+ identifier .sourceLocation ()));
12701314 var pair = getRegisterFile (expr );
12711315 var registerFile = pair .left ();
12721316 var index = pair .right ();
@@ -1319,12 +1363,21 @@ private Map<Identifier, Expr> aliasLookupTable(List<Definition> definitions) {
13191363 */
13201364 private SpecialPurposeRegisterDefinition getSpecialPurposeRegisterDefinition (
13211365 List <Definition > definitions , SpecialPurposeRegisterDefinition .Purpose purpose ) {
1366+ return getOptionalSpecialPurposeRegisterDefinition (definitions , purpose ).get ();
1367+ }
1368+
1369+ /**
1370+ * Extracts a {@link SpecialPurposeRegisterDefinition} with the given {@code purpose}.
1371+ * It is ok to find no definition.
1372+ */
1373+ private Optional <SpecialPurposeRegisterDefinition > getOptionalSpecialPurposeRegisterDefinition (
1374+ List <Definition > definitions , SpecialPurposeRegisterDefinition .Purpose purpose ) {
13221375 var registers = definitions
13231376 .stream ()
13241377 .filter (x -> x instanceof SpecialPurposeRegisterDefinition y && y .purpose == purpose )
13251378 .toList ();
13261379
1327- return ( SpecialPurposeRegisterDefinition ) registers .stream ().findFirst ().get ( );
1380+ return registers .stream ().findFirst ().map ( x -> ( SpecialPurposeRegisterDefinition ) x );
13281381 }
13291382
13301383
0 commit comments