CIRCT 23.0.0git
Loading...
Searching...
No Matches
ArcRuntime.cpp
Go to the documentation of this file.
1//===- ArcRuntime.cpp - Default implementation of the ArcRuntime-----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides the default implementation of a runtime library for
10// arcilator simulations.
11//
12//===----------------------------------------------------------------------===//
13
14#define ARC_RUNTIME_ENABLE_EXPORT
15
23#include "llvm/ADT/APInt.h"
24#include "llvm/ADT/ArrayRef.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/Support/raw_ostream.h"
27
28#ifdef ARC_RUNTIME_JIT_BIND
29#define ARC_RUNTIME_JITBIND_FNDECL
31#endif
32
33#include <cassert>
34#include <cstdarg>
35#include <cstdint>
36#include <cstdlib>
37#include <iostream>
38
39using namespace circt::arc::runtime;
40
41static inline impl::ModelInstance *getModelInstance(const ArcState *instance) {
42 assert(instance->impl != nullptr && "Instance is null");
43 return reinterpret_cast<impl::ModelInstance *>(instance->impl);
44}
45
47 const char *args) {
48 if (model->apiVersion != ARC_RUNTIME_API_VERSION) {
49 impl::fatalError("API version mismatch.\nMake sure to use an ArcRuntime "
50 "release matching "
51 "the arcilator version used to build the hardware model.");
52 return nullptr;
53 }
54
55 auto *statePtr = reinterpret_cast<ArcState *>(
56 calloc(1, sizeof(ArcState) + model->numStateBytes));
57 assert(reinterpret_cast<intptr_t>(&statePtr->modelState[0]) % 16 == 0 &&
58 "Simulation state must be 16 byte aligned");
59 statePtr->impl = new impl::ModelInstance(model, args, statePtr);
60 statePtr->magic = ARC_RUNTIME_MAGIC;
61 return statePtr;
62}
63
65 if (instance->impl)
66 delete reinterpret_cast<impl::ModelInstance *>(instance->impl);
67 free(instance);
68}
69
71
72void arcRuntimeOnEval(ArcState *instance) {
73 getModelInstance(instance)->onEval(instance);
74}
75
77 getModelInstance(instance)->onInitialized(instance);
78}
79
81 uint64_t offset) {
82 if (!modelState)
83 impl::fatalError("State pointer is null");
84 uint8_t *modPtr = static_cast<uint8_t *>(modelState) - offset;
85 ArcState *statePtr = reinterpret_cast<ArcState *>(modPtr - sizeof(ArcState));
86 if (statePtr->magic != ARC_RUNTIME_MAGIC)
87 impl::fatalError("Incorrect magic number for state");
88 return statePtr;
89}
90
91// --- IR Exports ---
92
94 const char *args) {
95 ArcState *statePtr = arcRuntimeAllocateInstance(model, args);
96 return statePtr->modelState;
97}
98
99void arcRuntimeIR_onEval(uint8_t *modelState) {
101}
102
103void arcRuntimeIR_onInitialized(uint8_t *modelState) {
105}
106
110
111static void formatToStream(llvm::raw_ostream &os, const FmtDescriptor *fmt,
112 va_list args) {
113 while (fmt->action != FmtDescriptor::Action_End) {
114 switch (fmt->action) {
116 std::string_view s(va_arg(args, const char *), fmt->literal.width);
117 os << s;
118 break;
119 }
121 std::string_view s(fmt->smallLiteral.data);
122 os << s;
123 break;
124 }
126 uint64_t *words = va_arg(args, uint64_t *);
127 int64_t numWords = llvm::divideCeil(fmt->intFmt.bitwidth, 64);
128 llvm::APInt apInt(fmt->intFmt.bitwidth, llvm::ArrayRef(words, numWords));
129 std::optional<int32_t> specifierWidth;
130 if (fmt->intFmt.specifierWidth >= 0)
131 specifierWidth = fmt->intFmt.specifierWidth;
132 circt::formatInteger(os, apInt, fmt->intFmt.radix,
134 fmt->intFmt.paddingChar, specifierWidth,
135 fmt->intFmt.isSigned);
136 break;
137 }
139 os << static_cast<char>(va_arg(args, int));
140 break;
142 break;
143 }
144 fmt++;
145 }
146}
147
148void arcRuntimeIR_format(const FmtDescriptor *fmt, ...) {
149 va_list args;
150 va_start(args, fmt);
151
152 formatToStream(llvm::outs(), fmt, args);
153
154 va_end(args);
155}
156
157void arcRuntimeIR_formatToStream(uint8_t *stream, const FmtDescriptor *fmt,
158 ...) {
159 if (!stream)
160 impl::fatalError("Output stream pointer is null");
161
162 va_list args;
163 va_start(args, fmt);
164
165 formatToStream(*reinterpret_cast<llvm::raw_ostream *>(stream), fmt, args);
166
167 va_end(args);
168}
169
171 return reinterpret_cast<uint8_t *>(&llvm::outs());
172}
173
175 return reinterpret_cast<uint8_t *>(&llvm::errs());
176}
177
178uint64_t *arcRuntimeIR_swapTraceBuffer(const uint8_t *modelState) {
179 auto *modPtr = static_cast<const uint8_t *>(modelState);
180 auto *statePtr =
181 reinterpret_cast<const ArcState *>(modPtr - sizeof(ArcState));
182 if (statePtr->magic != ARC_RUNTIME_MAGIC)
183 impl::fatalError("Incorrect magic number for state");
184 return getModelInstance(statePtr)->swapTraceBuffer();
185}
186
187#ifdef ARC_RUNTIME_JIT_BIND
188namespace circt::arc::runtime {
189
190static const APICallbacks apiCallbacksGlobal{
196
197const APICallbacks &getArcRuntimeAPICallbacks() { return apiCallbacksGlobal; }
198
199} // namespace circt::arc::runtime
200#endif
ArcState * arcRuntimeAllocateInstance(const ArcRuntimeModelInfo *model, const char *args)
uint64_t arcRuntimeGetAPIVersion()
Return the API version of the runtime library.
void arcRuntimeDeleteInstance(ArcState *instance)
Destroy and deallocate the state of a model instance.
void arcRuntimeIR_formatToStream(uint8_t *stream, const FmtDescriptor *fmt,...)
Prints a formatted string to the given stream.
void arcRuntimeOnEval(ArcState *instance)
Pre-Eval hook. Must be called by the driver once before every eval step.
void arcRuntimeIR_format(const FmtDescriptor *fmt,...)
Prints a formatted string to stdout.
uint8_t * arcRuntimeIR_getStdoutStream()
Return the standard output stream.
uint8_t * arcRuntimeIR_allocInstance(const ArcRuntimeModelInfo *model, const char *args)
Allocate and initialize the state for a new instance of the given hardware model.
void arcRuntimeOnInitialized(ArcState *instance)
Must be called by the driver after the model's initial function and before the first onEval call.
uint64_t * arcRuntimeIR_swapTraceBuffer(const uint8_t *modelState)
Release the active trace buffer and request an empty new buffer.
uint8_t * arcRuntimeIR_getStderrStream()
Return the standard error stream.
void arcRuntimeIR_deleteInstance(uint8_t *modelState)
Destroy and deallocate the state of a model instance.
static void formatToStream(llvm::raw_ostream &os, const FmtDescriptor *fmt, va_list args)
ArcState * arcRuntimeGetStateFromModelState(uint8_t *modelState, uint64_t offset)
Project a pointer to the model state to its ArcState container.
static impl::ModelInstance * getModelInstance(const ArcState *instance)
void arcRuntimeIR_onEval(uint8_t *modelState)
Pre-Eval hook of the runtime library.
void arcRuntimeIR_onInitialized(uint8_t *modelState)
Post-initialization hook of the runtime library.
assert(baseType &&"element must be base type")
ARC_IR_EXPORT uint8_t * arcRuntimeIR_getStderrStream()
Return the standard error stream.
ARC_IR_EXPORT void arcRuntimeIR_formatToStream(uint8_t *stream, const circt::arc::runtime::FmtDescriptor *fmt,...)
Prints a formatted string to the given stream.
ARC_IR_EXPORT uint8_t * arcRuntimeIR_getStdoutStream()
Return the standard output stream.
ARC_IR_EXPORT uint8_t * arcRuntimeIR_allocInstance(const ArcRuntimeModelInfo *model, const char *args)
Allocate and initialize the state for a new instance of the given hardware model.
ARC_IR_EXPORT void arcRuntimeIR_deleteInstance(uint8_t *modelState)
Destroy and deallocate the state of a model instance.
ARC_IR_EXPORT void arcRuntimeIR_onEval(uint8_t *modelState)
Pre-Eval hook of the runtime library.
ARC_IR_EXPORT void arcRuntimeIR_onInitialized(uint8_t *modelState)
Post-initialization hook of the runtime library.
ARC_IR_EXPORT uint64_t * arcRuntimeIR_swapTraceBuffer(const uint8_t *modelState)
Release the active trace buffer and request an empty new buffer.
ARC_IR_EXPORT void arcRuntimeIR_format(const circt::arc::runtime::FmtDescriptor *fmt,...)
Prints a formatted string to stdout.
#define ARC_RUNTIME_MAGIC
Magic number used to assert the presence of an ArcState struct.
Definition Common.h:30
#define ARC_RUNTIME_API_VERSION
Version of the combined public and internal API.
Definition Common.h:27
void formatInteger(llvm::raw_ostream &os, const llvm::APInt &value, unsigned radix, bool isUpperCase, bool isLeftAligned, char paddingChar, std::optional< int32_t > specifierWidth, bool isSigned)
Format value in the given radix and emit it to os, padded to a field width.
Static information for a compiled hardware model, generated by the MLIR lowering.
Definition Common.h:70
uint64_t apiVersion
Runtime API version used when compiling the model.
Definition Common.h:72
uint64_t numStateBytes
Number of bytes required for the model's state.
Definition Common.h:74
Combined runtime and model state for a hardware model instance.
Definition Common.h:44
void * impl
Runtime implementation specific data. Usually points to a custom struct.
Definition Common.h:46
uint8_t modelState[]
Definition Common.h:58
uint32_t magic
Runtime magic number. Must be set to ARC_RUNTIME_MAGIC.
Definition Common.h:54
bool isLeftAligned
Whether the value is left aligned.
bool isSigned
Whether to treat the value as signed.
bool isUpperCase
Whether to use uppercase hex letters.
char paddingChar
Padding character (NUL if no padding is desired).
int16_t specifierWidth
The minumum width of the output in characters.
int16_t bitwidth
The bitwidth of the integer value.
int8_t radix
The radix to use for formatting. Must be one of {2, 8, 10, 16}.
int64_t width
The width of the literal string in characters.
A format descriptor, to be given to arcRuntimeFormat.
@ Action_Char
Prints a character (c).
@ Action_Literal
Prints a literal string.
@ Action_End
End of the format string, no action to take.
@ Action_LiteralSmall
Prints a literal string (small string optimization).