Skip to content

Commit 2fa5aaa

Browse files
authored
Merge pull request #77 from OpenVADL/feature/21-allow-field-access-function-in-assembly
lcb: Support multiple immediates and field access functions
2 parents a728e0c + 4e4ebb6 commit 2fa5aaa

File tree

17 files changed

+209
-235
lines changed

17 files changed

+209
-235
lines changed

vadl/main/resources/templates/lcb/llvm/lib/Target/AsmParser/AsmParser.cpp

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class [(${namespace})]AsmParser : public MCTargetAsmParser {
2626
return static_cast<[(${namespace})]TargetStreamer &>(TS);
2727
}
2828

29-
bool ModifyImmediate(unsigned OpCode, StringRef OpName, [(${namespace})]ParsedOperand &Op);
29+
bool ModifyImmediate(unsigned OpIndex, unsigned OpCode, StringRef OpName, [(${namespace})]ParsedOperand &Op);
3030

3131
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3232
OperandVector &Operands, MCStreamer &Out,
@@ -104,7 +104,7 @@ bool [(${namespace})]AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &O
104104
auto parsedTarget = op.getTarget();
105105
if( parsedTarget == searchTarget )
106106
{
107-
if(!ModifyImmediate(Opcode, parsedTarget, op))
107+
if(!ModifyImmediate(i, Opcode, parsedTarget, op))
108108
{
109109
return true;
110110
}
@@ -191,48 +191,44 @@ void [(${namespace})]AsmParser::convertToMapAndConstraints(unsigned Kind,
191191
const OperandVector &Operands) {
192192
}
193193

194-
bool [(${namespace})]AsmParser::ModifyImmediate(unsigned Opcode, StringRef OpName, [(${namespace})]ParsedOperand &Op)
194+
bool [(${namespace})]AsmParser::ModifyImmediate(unsigned OpIndex, unsigned Opcode, StringRef OpName, [(${namespace})]ParsedOperand &Op)
195195
{
196196
if(!Op.isImm() || Op.getImm()->getKind() != MCExpr::ExprKind::Constant)
197197
return true;
198198

199199
int64_t opImm64 = dyn_cast<MCConstantExpr>(Op.getImm())->getValue();
200-
switch(Opcode)
201-
{
202-
default: return true;
203-
[# th:each="conversion : ${immediateConversions}" ]
204-
[# th:if="${conversion.emitConversion}" ]
205-
case([(${namespace})]::[(${conversion.insnName})]):
206-
{
207-
if (OpName.equals_insensitive("[(${conversion.operandName})]")) {
208-
// check if immediate is in ([(${conversion.lowestValue})],[(${conversion.highestValue})])
209-
if (opImm64 < [(${conversion.lowestValue})] || opImm64 > [(${conversion.highestValue})]) {
210-
std::string error = "Invalid immediate operand for [(${conversion.insnName})].[(${conversion.operandName})]. Value "
211-
+ std::to_string(opImm64) + " is out of the valid range ([(${conversion.lowestValue})],[(${conversion.highestValue})]).";
212-
Parser.Error(Op.getStartLoc(), error);
213-
return false;
214-
}
215-
[# th:if="${conversion.needsDecode}" ]
216-
opImm64 = [(${conversion.decodeMethod})](opImm64);
217-
[/]
218-
// check if immediate fits the provided predicate for the instruction
219-
if(![(${conversion.predicateMethod})](opImm64))
220-
{
221-
std::string error = "Invalid immediate operand for [(${conversion.insnName})].[(${conversion.operandName})]. The predicate does not hold.";
222-
Parser.Error(Op.getStartLoc(), error);
223-
return false;
224-
}
225200

226-
const MCExpr* constantExpr = MCConstantExpr::create(opImm64, Parser.getContext());
227-
Op = [(${namespace})]ParsedOperand::CreateImm(constantExpr, Op.getStartLoc(), Op.getEndLoc());
228-
} else {
229-
const MCExpr* constantExpr = MCConstantExpr::create(opImm64, Parser.getContext());
230-
Op = [(${namespace})]ParsedOperand::CreateImm(constantExpr, Op.getStartLoc(), Op.getEndLoc());
201+
[# th:each="conversion : ${immediateConversions}" ]
202+
if(Opcode == [(${namespace})]::[(${conversion.insnName})] && OpIndex == [(${conversion.opIndex})])
203+
{
204+
if (OpName.equals_insensitive("[(${conversion.operandName})]")) {
205+
// check if immediate is in ([(${conversion.lowestValue})],[(${conversion.highestValue})])
206+
if (opImm64 < [(${conversion.lowestValue})] || opImm64 > [(${conversion.highestValue})]) {
207+
std::string error = "Invalid immediate operand for [(${conversion.insnName})].[(${conversion.operandName})]. Value "
208+
+ std::to_string(opImm64) + " is out of the valid range ([(${conversion.lowestValue})],[(${conversion.highestValue})]).";
209+
Parser.Error(Op.getStartLoc(), error);
210+
return false;
231211
}
212+
[# th:if="${conversion.needsDecode}" ]
213+
opImm64 = [(${conversion.decodeMethod})](opImm64);
214+
[/]
215+
// check if immediate fits the provided predicate for the instruction
216+
if(![(${conversion.predicateMethod})](opImm64))
217+
{
218+
std::string error = "Invalid immediate operand for [(${conversion.insnName})].[(${conversion.operandName})]. The predicate does not hold.";
219+
Parser.Error(Op.getStartLoc(), error);
220+
return false;
221+
}
222+
223+
const MCExpr* constantExpr = MCConstantExpr::create(opImm64, Parser.getContext());
224+
Op = [(${namespace})]ParsedOperand::CreateImm(constantExpr, Op.getStartLoc(), Op.getEndLoc());
232225
return true;
233-
break;
234-
}[/][/]
235-
}
226+
} else {
227+
const MCExpr* constantExpr = MCConstantExpr::create(opImm64, Parser.getContext());
228+
Op = [(${namespace})]ParsedOperand::CreateImm(constantExpr, Op.getStartLoc(), Op.getEndLoc());
229+
return true;
230+
}
231+
}[/]
236232
return true;
237233
}
238234

vadl/main/resources/templates/lcb/llvm/lib/Target/MCTargetDesc/TargetInstPrinter.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ MCOperand [(${namespace})]InstPrinter::adjustImmediateOp
5656
[# th:each="instruction : ${instructionWithEncodedImmediate}" ]
5757
case [(${namespace})]::[(${instruction.identifier})]:
5858
{
59-
auto newOp = [(${instruction.rawEncoderMethod})](value);
60-
return MCOperand::createImm(newOp);
59+
if(OpIndex == [(${instruction.opIndex})]) {
60+
auto newOp = [(${instruction.rawEncoderMethod})](value);
61+
return MCOperand::createImm(newOp);
62+
}
6163
}
6264
[/]
6365
}

vadl/main/vadl/lcb/passes/DummyAnnotationPass.java

Lines changed: 0 additions & 66 deletions
This file was deleted.

vadl/main/vadl/lcb/passes/llvmLowering/GenerateTableGenMachineInstructionRecordPass.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public List<TableGenMachineInstruction> execute(PassResults passResults, Specifi
6969
instruction.identifier.simpleName(),
7070
lcbConfiguration().targetName().value(),
7171
instruction,
72+
result,
7273
result.info().flags(),
7374
result.info().inputs(),
7475
result.info().outputs(),

vadl/main/vadl/lcb/passes/llvmLowering/LlvmLoweringPass.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import vadl.lcb.passes.llvmLowering.strategies.instruction.conditionals.LlvmInstructionLoweringLessThanSignedConditionalsStrategyImpl;
6060
import vadl.lcb.passes.llvmLowering.strategies.instruction.conditionals.LlvmInstructionLoweringLessThanUnsignedConditionalsStrategyImpl;
6161
import vadl.lcb.passes.llvmLowering.tablegen.model.ReferencesFormatField;
62+
import vadl.lcb.passes.llvmLowering.tablegen.model.ReferencesImmediateOperand;
6263
import vadl.lcb.passes.llvmLowering.tablegen.model.TableGenInstAlias;
6364
import vadl.lcb.passes.llvmLowering.tablegen.model.TableGenInstruction;
6465
import vadl.lcb.passes.llvmLowering.tablegen.model.tableGenOperand.TableGenInstructionImmediateLabelOperand;
@@ -100,6 +101,16 @@ public record BaseInstructionInfo(List<TableGenInstructionOperand> inputs,
100101
LlvmLoweringPass.Flags flags,
101102
List<RegisterRef> uses,
102103
List<RegisterRef> defs) {
104+
/**
105+
* Get the input operands which are immediates.
106+
*/
107+
public List<ReferencesImmediateOperand> inputImmediates() {
108+
return inputs.stream()
109+
.filter(x -> x instanceof ReferencesImmediateOperand)
110+
.map(x -> (ReferencesImmediateOperand) x)
111+
.toList();
112+
}
113+
103114
/**
104115
* Find the index in the {@link #inputs} by the given field.
105116
*/

vadl/main/vadl/lcb/passes/llvmLowering/domain/LlvmLoweringRecord.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public static class Machine extends LlvmLoweringRecord {
5858
/**
5959
* Constructor.
6060
*/
61-
public Machine(Instruction instructionRef, LlvmLoweringPass.BaseInstructionInfo info,
61+
public Machine(Instruction instructionRef,
62+
LlvmLoweringPass.BaseInstructionInfo info,
6263
List<TableGenPattern> patterns) {
6364
super(info, patterns);
6465
this.instructionRef = instructionRef;

vadl/main/vadl/lcb/passes/EncodeAssemblyImmediateAnnotation.java renamed to vadl/main/vadl/lcb/passes/llvmLowering/tablegen/model/ReferencesImmediateOperand.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,22 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616

17-
package vadl.lcb.passes;
17+
package vadl.lcb.passes.llvmLowering.tablegen.model;
1818

19-
import vadl.viam.Annotation;
20-
import vadl.viam.Assembly;
19+
import vadl.lcb.passes.llvmLowering.tablegen.model.tableGenOperand.tableGenParameter.TableGenParameter;
2120

2221
/**
23-
* Annotation to indicate that the immediate in the {@link Assembly} needs to be emitted
24-
* before printing.
25-
*/
26-
public class EncodeAssemblyImmediateAnnotation extends Annotation<Assembly> {
27-
@Override
28-
public Class<Assembly> parentDefinitionClass() {
29-
return Assembly.class;
30-
}
22+
* Indicator interface which indicates that the operand is referencing
23+
* a {@link TableGenImmediateRecord}.
24+
*/
25+
public interface ReferencesImmediateOperand {
26+
/**
27+
* Get the field from the operand.
28+
*/
29+
TableGenImmediateRecord immediateOperand();
30+
31+
/**
32+
* Get the TableGen parameter.
33+
*/
34+
TableGenParameter parameter();
3135
}

vadl/main/vadl/lcb/passes/llvmLowering/tablegen/model/TableGenInstruction.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,11 @@ public String getName() {
9090
return name;
9191
}
9292

93-
93+
/**
94+
* Get the operand index in {@link #inOperands}. It is offset by the number of operands
95+
* in {@link #outOperands}.
96+
*/
97+
public int indexInOperands(TableGenInstructionOperand operand) {
98+
return outOperands.size() + inOperands.indexOf(operand);
99+
}
94100
}

vadl/main/vadl/lcb/passes/llvmLowering/tablegen/model/TableGenMachineInstruction.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Optional;
2525
import java.util.stream.Stream;
2626
import vadl.lcb.passes.llvmLowering.LlvmLoweringPass;
27+
import vadl.lcb.passes.llvmLowering.domain.LlvmLoweringRecord;
2728
import vadl.lcb.passes.llvmLowering.domain.RegisterRef;
2829
import vadl.lcb.passes.llvmLowering.tablegen.model.tableGenOperand.TableGenInstructionOperand;
2930
import vadl.viam.Instruction;
@@ -38,14 +39,16 @@ public class TableGenMachineInstruction extends TableGenInstruction {
3839
private final List<BitBlock> bitBlocks;
3940
private final List<FieldEncoding> fieldEncodings;
4041
private final Instruction instruction;
42+
private final LlvmLoweringRecord.Machine llvmLoweringRecord;
4143

4244

4345
/**
44-
* Constructor for an instruction in TableGen.
46+
* Constructor for an instruction in TableGen. It wraps the {@link LlvmLoweringRecord}.
4547
*/
4648
public TableGenMachineInstruction(String name,
4749
String namespace,
4850
Instruction instruction,
51+
LlvmLoweringRecord.Machine llvmLoweringRecord,
4952
LlvmLoweringPass.Flags flags,
5053
List<TableGenInstructionOperand> inOperands,
5154
List<TableGenInstructionOperand> outOperands,
@@ -59,6 +62,7 @@ public TableGenMachineInstruction(String name,
5962
this.bitBlocks = BitBlock.from(instruction.encoding());
6063
this.fieldEncodings = FieldEncoding.from(instruction.encoding());
6164
this.instruction = instruction;
65+
this.llvmLoweringRecord = llvmLoweringRecord;
6266
}
6367

6468

@@ -86,6 +90,10 @@ public Instruction instruction() {
8690
return instruction;
8791
}
8892

93+
public LlvmLoweringRecord.Machine llvmLoweringRecord() {
94+
return llvmLoweringRecord;
95+
}
96+
8997
/**
9098
* A machine instruction has certain encoding parts which are fixed like the opcode.
9199
* A {@link BitBlock} represents constant bits in an instruction.

vadl/main/vadl/lcb/passes/llvmLowering/tablegen/model/tableGenOperand/TableGenInstructionImmediateLabelOperand.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import vadl.lcb.passes.llvmLowering.domain.selectionDag.LlvmBasicBlockSD;
2424
import vadl.lcb.passes.llvmLowering.domain.selectionDag.LlvmFieldAccessRefNode;
2525
import vadl.lcb.passes.llvmLowering.tablegen.model.ReferencesFormatField;
26+
import vadl.lcb.passes.llvmLowering.tablegen.model.ReferencesImmediateOperand;
2627
import vadl.lcb.passes.llvmLowering.tablegen.model.TableGenImmediateRecord;
2728
import vadl.lcb.passes.llvmLowering.tablegen.model.tableGenOperand.tableGenParameter.TableGenParameterTypeAndName;
2829
import vadl.viam.Format;
@@ -31,7 +32,7 @@
3132
* Indicates that the operand is an immediate but as a label.
3233
*/
3334
public class TableGenInstructionImmediateLabelOperand extends TableGenInstructionOperand
34-
implements ReferencesFormatField {
35+
implements ReferencesFormatField, ReferencesImmediateOperand {
3536
private final TableGenImmediateRecord immediateOperand;
3637

3738
/**
@@ -56,6 +57,7 @@ public TableGenInstructionImmediateLabelOperand(LlvmFieldAccessRefNode node) {
5657
this.immediateOperand = node.immediateOperand();
5758
}
5859

60+
@Override
5961
public TableGenImmediateRecord immediateOperand() {
6062
return immediateOperand;
6163
}

0 commit comments

Comments
 (0)