Exemplo n.º 1
0
bool CompileFunction(CompileInstance &inst, const mtlChars &ret_type, const mtlChars &name, const mtlChars &params, const mtlChars &body)
{
    if (!IsGlobal(inst)) { // TODO: I want to support this eventually, but I need to emit jump instructions
        AddError(inst, "Nested functions not allowed", name);
        return false;
    }

    PushScope(inst, false);
    inst.scopes.GetLast()->GetItem().rel_sptr = 0; // reset the relative stack pointer
    bool result = true;
    bool is_main = false;
    result &= DeclareVar(inst, ret_type, name, "");

    if (name.Compare("main", true)) {
        ++inst.main;
        if (inst.main > 1) {
            AddError(inst, "Multiple entry points", "");
            return false;
        }
        *inst.prog_entry = (char)inst.program.GetSize();
        is_main = true;
    }

    Parser p;
    p.SetBuffer(params);
    mtlList<mtlChars> m;
    int stack_start = inst.scopes.GetLast()->GetItem().size;
    while (!p.IsEnd()) {
        if (p.MatchPart("%w%w", m, NULL) == 0) {
            result &= DeclareVar(inst, m.GetFirst()->GetItem(), m.GetFirst()->GetNext()->GetItem(), "");
        } else {
            AddError(inst, "Parameter syntax", params);
            return false;
        }
        p.MatchPart(",", m);
    }
    int stack_end = inst.scopes.GetLast()->GetItem().size;
    result &= CompileScope(inst, body, false);
    PopScope(inst);
    if (is_main) {
        *inst.prog_inputs = stack_end - stack_start;
        EmitInstruction(inst, swsl::END);
    } else {
        // FIX: This is a placeholder to prevent the compiler from optimizing stack manipulations
        EmitInstruction(inst, swsl::NOP); // this should emit a SET instruction (set the value of the return value)
    }
    return result;
}
Exemplo n.º 2
0
/// encodeInstruction - Emit the instruction.
/// Size the instruction (currently only 4 bytes)
void Cpu0MCCodeEmitter::
encodeInstruction(const MCInst &MI, raw_ostream &OS,
                  SmallVectorImpl<MCFixup> &Fixups,
                  const MCSubtargetInfo &STI) const
{
  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);

  // Check for unimplemented opcodes.
  // Unfortunately in CPU0 both NOT and SLL will come in with Binary == 0
  // so we have to special check for them.
  unsigned Opcode = MI.getOpcode();
  if ((Opcode != Cpu0::NOP) && (Opcode != Cpu0::SHL) && !Binary)
    llvm_unreachable("unimplemented opcode in encodeInstruction()");

  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
  uint64_t TSFlags = Desc.TSFlags;

  // Pseudo instructions don't get encoded and shouldn't be here
  // in the first place!
  if ((TSFlags & Cpu0II::FormMask) == Cpu0II::Pseudo)
    llvm_unreachable("Pseudo opcode found in encodeInstruction()");

  // For now all instructions are 4 bytes
  int Size = 4; // FIXME: Have Desc.getSize() return the correct value!

  EmitInstruction(Binary, Size, OS);
}
Exemplo n.º 3
0
void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &OS) const {
    // Output the instruction encoding in little endian byte order.
    // Little-endian byte ordering:
    //   mips32r2:   4 | 3 | 2 | 1
    //   microMIPS:  2 | 1 | 4 | 3
    if (IsLittleEndian && Size == 4 && isMicroMips(STI)) {
        EmitInstruction(Val >> 16, 2, STI, OS);
        EmitInstruction(Val, 2, STI, OS);
    } else {
Exemplo n.º 4
0
bool AssignVar(CompileInstance &inst, const mtlChars &name, const mtlChars &expr)
{
    mtlChars base_name = GetBaseName(name);
    Definition *type = GetType(inst, base_name);
    if (type == NULL) {
        AddError(inst, "Undeclared variable", name);
        return false;
    }
    if (type->mut != Mutable) {
        AddError(inst, "Modifying a constant", name);
        return false;
    }

    ExpressionNode *tree = GenerateTree(expr);
    if (tree == NULL) {
        AddError(inst, "Malformed expression", expr);
        return false;
    }

    mtlChars          base_mem = GetBaseMembers(name);
    bool              result = true;
    Parser            parser;
    mtlList<mtlChars> ops;
    mtlList<mtlChars> m;
    mtlString         order_str;
    const int         num_lanes = (base_mem.GetSize() > 0) ? base_mem.GetSize() : type->type.size;

    for (int lane = 0; lane < num_lanes; ++lane) {

        order_str.Free();
        const int stack_size = tree->Evaluate(name, order_str, lane, 0);

        PushStack(inst, stack_size);

        order_str.SplitByChar(ops, ';');
        mtlItem<mtlChars> *op = ops.GetFirst();

        while (op != NULL && op->GetItem().GetSize() > 0) {

            parser.SetBuffer(op->GetItem());

            switch (parser.MatchPart("%s+=%s%|%s-=%s%|%s*=%s%|%s/=%s%|%s=%s", m, NULL)) {
            case 0:
                EmitInstruction(inst, swsl::FLT_ADD_MM);
                break;
            case 1:
                EmitInstruction(inst, swsl::FLT_SUB_MM);
                break;
            case 2:
                EmitInstruction(inst, swsl::FLT_MUL_MM);
                break;
            case 3:
                EmitInstruction(inst, swsl::FLT_DIV_MM);
                break;
            case 4:
                EmitInstruction(inst, swsl::FLT_SET_MM);
                break;
            default:
                AddError(inst, "Invalid syntax", op->GetItem());
                return false;
                break;
            }

            mtlItem<swsl::Instruction> *instr_item = inst.program.GetLast();

            const mtlChars dst = m.GetFirst()->GetItem();
            const mtlChars src = m.GetFirst()->GetNext()->GetItem();

            EmitOperand(inst, dst);
            if (src.IsFloat()) {
                *((int*)(&instr_item->GetItem().instr)) += 1;
            }
            EmitOperand(inst, src);

            op = op->GetNext();
        }

        PopStack(inst, stack_size);
    }

    delete tree;

    return result;
}