package de.fuberlin.optimierung.commands;
import de.fuberlin.optimierung.*;
/*
* Syntax:
<result> = [tail] call [cconv] [ret attrs] <ty> [<fnty>*] <fnptrval>(<function args>) [fn attrs]
*/
public class LLVM_CallCommand extends LLVM_GenericCommand{
private boolean tail = false;
private boolean startsnotwithcall = false;
private String cconv = "";
private String reta = "";
private String fnty = "";
private String fnptrval = "";
private String fnattrs = "";
private boolean hasElemPtr = false;
private boolean hasInbounds = false;
private String getElemPtrVal = "";
private int getElemPtrCount = 0;
public LLVM_CallCommand(String cmdLine, LLVM_GenericCommand predecessor, LLVM_Block block){
super(predecessor, block, cmdLine);
setOperation(LLVM_Operation.CALL);
StringBuilder cmd = new StringBuilder(cmdLine);
parseEraseComment(cmd);
hasElemPtr = cmdLine.contains("getelementptr");
String result = "";
if (!cmdLine.startsWith("call ")){
startsnotwithcall = true;
result = parseReadResult(cmd);
tail = parseOptionalString(cmd, "tail");
}
parseEraseString(cmd, "call");
cconv = parseOptionalListSingle(cmd, new String[]{"ccc", "fastcc", "coldcc", "cc "});
reta = parseOptionalList(cmd, new String[]{"zeroext", "signext", "inreg"});
String ty = parseReadType(cmd);
if (cmd.toString().indexOf('@') > 0){
// optionaler Pointer nur vorhanden, wenn @ nicht am Anfang steht
fnty = parseReadType(cmd);
}
fnptrval = parseReadValue(cmd);
// <result> <ty>
target = new LLVM_Parameter(result, ty);
parseEraseString(cmd, "(");
String funcargs = parseStringUntil(cmd, ")");
if (hasElemPtr){
parseEraseString(cmd, ")");
StringBuilder getelem = new StringBuilder(funcargs);
// getelem = i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0
getElemPtrVal = parseReadType(getelem);
parseEraseString(getelem, "getelementptr");
if (parseOptionalString(getelem, "inbounds")) hasInbounds = true;
parseEraseString(getelem, "(");
String pty = parseReadPointer(getelem);
String ptyval = parseReadValue(getelem);
operands.add(new LLVM_Parameter(ptyval, pty));
while (parseEraseString(getelem, ",")){
String typ = parseReadType(getelem);
String idx = parseReadValue(getelem);
operands.add(new LLVM_Parameter(idx, typ));
}
getElemPtrCount = operands.size();
funcargs = parseStringUntil(cmd, ")");
}
parseEraseString(cmd, ")");
fnattrs = parseOptionalList(cmd, new String[]{"noreturn", "nounwind", "readnone", "readonly"});
if (funcargs.startsWith(",")){
// Korrektur für GetElemPtr
// Komma entfernen
funcargs = funcargs.substring(1).trim();
}
//func args verarbeiten
if (funcargs.length() > 0){
StringBuilder tmp = new StringBuilder(funcargs);
do{
String typ = parseReadType(tmp);
String name = parseReadValue(tmp);
operands.add(new LLVM_Parameter(name, typ));
}while(parseEraseString(tmp, ","));
}
if (LLVM_Optimization.DEBUG) System.out.println("Operation generiert: " + this.toString());
}
public String toString() {
if (target == null || operands == null) return null;
String cmd_out = "";
if (startsnotwithcall){
cmd_out += target.getName() + " = ";
if (tail) cmd_out += "tail ";
}
cmd_out += "call ";
if (cconv != "") cmd_out += cconv + " ";
if (reta != "") cmd_out += reta + " ";
cmd_out += target.getTypeString() + " ";
if (fnty != "") cmd_out += fnty + " ";
if (fnptrval != "") cmd_out += fnptrval;
cmd_out += "(";
if (hasElemPtr){
// getelem = i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0
cmd_out += getElemPtrVal + " getelementptr ";
if (hasInbounds) cmd_out += "inbounds ";
cmd_out += "(";
if (operands.size() > 0){
for (int i = 0; i < getElemPtrCount; i++){
cmd_out += operands.get(i).getTypeString() + " " + operands.get(i).getName();
if (i+1 < getElemPtrCount) cmd_out += ", ";
}
}
cmd_out += ")";
}
if (operands.size() > getElemPtrCount && hasElemPtr) cmd_out += ", ";
if (operands.size() > 0){
for (int i = getElemPtrCount; i < operands.size(); i++){
cmd_out += operands.get(i).getTypeString() + " " + operands.get(i).getName();
if (i+1 < operands.size()) cmd_out += ", ";
}
}
cmd_out += ") ";
if (fnattrs != "") cmd_out += fnattrs + " ";
cmd_out += " " + getComment();
return cmd_out;
}
}