Ejemplo n.º 1
0
Error CodeBuilder::serialize(CodeEmitter* dst) {
  Error err = kErrorOk;
  CBNode* node_ = getFirstNode();

  do {
    dst->setInlineComment(node_->getInlineComment());

    switch (node_->getType()) {
      case CBNode::kNodeAlign: {
        CBAlign* node = static_cast<CBAlign*>(node_);
        err = dst->align(node->getMode(), node->getAlignment());
        break;
      }

      case CBNode::kNodeData: {
        CBData* node = static_cast<CBData*>(node_);
        err = dst->embed(node->getData(), node->getSize());
        break;
      }

      case CBNode::kNodeFunc:
      case CBNode::kNodeLabel: {
        CBLabel* node = static_cast<CBLabel*>(node_);
        err = dst->bind(node->getLabel());
        break;
      }

      case CBNode::kNodeLabelData: {
        CBLabelData* node = static_cast<CBLabelData*>(node_);
        err = dst->embedLabel(node->getLabel());
        break;
      }

      case CBNode::kNodeConstPool: {
        CBConstPool* node = static_cast<CBConstPool*>(node_);
        err = dst->embedConstPool(node->getLabel(), node->getConstPool());
        break;
      }

      case CBNode::kNodeInst:
      case CBNode::kNodeFuncCall: {
        CBInst* node = static_cast<CBInst*>(node_);

        uint32_t instId = node->getInstId();
        uint32_t options = node->getOptions();

        const Operand* opArray = node->getOpArray();
        uint32_t opCount = node->getOpCount();

        const Operand_* o0 = &dst->_none;
        const Operand_* o1 = &dst->_none;
        const Operand_* o2 = &dst->_none;
        const Operand_* o3 = &dst->_none;

        switch (opCount) {
          case 6: dst->_op5 = opArray[5]; options |= CodeEmitter::kOptionOp5; ASMJIT_FALLTHROUGH;
          case 5: dst->_op4 = opArray[4]; options |= CodeEmitter::kOptionOp4; ASMJIT_FALLTHROUGH;
          case 4: o3 = &opArray[3]; ASMJIT_FALLTHROUGH;
          case 3: o2 = &opArray[2]; ASMJIT_FALLTHROUGH;
          case 2: o1 = &opArray[1]; ASMJIT_FALLTHROUGH;
          case 1: o0 = &opArray[0]; ASMJIT_FALLTHROUGH;
          case 0: break;
        }

        dst->setOptions(options);
        err = dst->_emit(instId, *o0, *o1, *o2, *o3);
        break;
      }

      case CBNode::kNodeComment: {
        CBComment* node = static_cast<CBComment*>(node_);
        err = dst->comment(node->getInlineComment());
        break;
      }

      default:
        break;
    }

    if (err) break;
    node_ = node_->getNext();
  } while (node_);

  return err;
}
Ejemplo n.º 2
0
Error CodeBuilder::serialize(CodeEmitter* dst) {
  Error err = kErrorOk;
  CBNode* node_ = getFirstNode();

  do {
    dst->setInlineComment(node_->getInlineComment());

    switch (node_->getType()) {
      case CBNode::kNodeAlign: {
        CBAlign* node = static_cast<CBAlign*>(node_);
        err = dst->align(node->getMode(), node->getAlignment());
        break;
      }

      case CBNode::kNodeData: {
        CBData* node = static_cast<CBData*>(node_);
        err = dst->embed(node->getData(), node->getSize());
        break;
      }

      case CBNode::kNodeFunc:
      case CBNode::kNodeLabel: {
        CBLabel* node = static_cast<CBLabel*>(node_);
        err = dst->bind(node->getLabel());
        break;
      }

      case CBNode::kNodeLabelData: {
        CBLabelData* node = static_cast<CBLabelData*>(node_);
        err = dst->embedLabel(node->getLabel());
        break;
      }

      case CBNode::kNodeConstPool: {
        CBConstPool* node = static_cast<CBConstPool*>(node_);
        err = dst->embedConstPool(node->getLabel(), node->getConstPool());
        break;
      }

      case CBNode::kNodeInst:
      case CBNode::kNodeFuncCall: {
        CBInst* node = node_->as<CBInst>();
        dst->setOptions(node->getOptions());
        dst->setExtraReg(node->getExtraReg());
        err = dst->emitOpArray(node->getInstId(), node->getOpArray(), node->getOpCount());
        break;
      }

      case CBNode::kNodeComment: {
        CBComment* node = static_cast<CBComment*>(node_);
        err = dst->comment(node->getInlineComment());
        break;
      }

      default:
        break;
    }

    if (err) break;
    node_ = node_->getNext();
  } while (node_);

  return err;
}