Example #1
0
func (this *Fpu) compute(op *operation.Operation, info *info.Info, operands interface{}) (uint32, error) {

	op1, op2, outputAddr, err := this.getOperands(info, operands)
	if err != nil {
		return 0, err
	}

	switch info.Opcode {
	case set.OP_FADD:
		val1 := this.Bus().LoadRegister(op, op1)
		val2 := this.Bus().LoadRegister(op, op2)
		this.SetResult(ieee754.PackFloat754_32(ieee754.UnPackFloat754_32(val1) + ieee754.UnPackFloat754_32(val2)))
	case set.OP_FSUB:
		val1 := this.Bus().LoadRegister(op, op1)
		val2 := this.Bus().LoadRegister(op, op2)
		this.SetResult(ieee754.PackFloat754_32(ieee754.UnPackFloat754_32(val1) - ieee754.UnPackFloat754_32(val2)))
	case set.OP_FMUL:
		val1 := this.Bus().LoadRegister(op, op1)
		val2 := this.Bus().LoadRegister(op, op2)
		this.SetResult(ieee754.PackFloat754_32(ieee754.UnPackFloat754_32(val1) * ieee754.UnPackFloat754_32(val2)))
	case set.OP_FDIV:
		val1 := this.Bus().LoadRegister(op, op1)
		val2 := this.Bus().LoadRegister(op, op2)
		this.SetResult(ieee754.PackFloat754_32(ieee754.UnPackFloat754_32(val1) / ieee754.UnPackFloat754_32(val2)))
	default:
		return 0, errors.New(fmt.Sprintf("Invalid operation to process by FPU unit. Opcode: %d", info.Opcode))
	}
	return outputAddr, nil
}
Example #2
0
func (this Set) GetInstructionFromString(line string, address uint32, labels map[string]uint32) (*instruction.Instruction, error) {

	// Clean line and split by items
	items, err := getItemsFromString(line)
	if err != nil {
		return nil, err
	}

	// Search opcode in the instruction set
	opInfo, err := this.GetInstructionInfoFromName(items[0])
	if err != nil {
		return nil, err
	}

	// Check all operands (except opcode/operation) is a numeric value
	operands := []uint32{uint32(opInfo.Opcode)}
	for _, value := range items[1:] {
		if strings.TrimSpace(value) == "" {
			continue
		}
		labelAddress, isLabel := labels[value]
		if isLabel {
			if opInfo.Type == data.TypeJ {
				offset := computeBranchAddress(labelAddress)
				operands = append(operands, offset)
			} else {
				offset := computeBranchOffset(labelAddress, address)
				operands = append(operands, offset)
			}
		} else {
			if opInfo.Category == info.FloatingPoint && !strings.Contains(value, "R") {
				floatValue, err := strconv.ParseFloat(value, consts.ARCHITECTURE_SIZE)
				if err != nil {
					return nil, errors.New(fmt.Sprintf("Expecting a float value and found: %s. %s", value, err.Error()))
				}
				operands = append(operands, ieee754.PackFloat754_32(float32(floatValue)))
			} else {
				integer, err := strconv.Atoi(strings.Replace(value, "R", "", -1))
				if err != nil {
					return nil, errors.New(fmt.Sprintf("Expecting an integer or RX operand and found: %s", value))
				}
				operands = append(operands, uint32(integer))
			}
		}
	}

	// Get data object from operands
	data, err := data.GetDataFromParts(opInfo.Type, operands...)
	if err != nil {
		return nil, err
	}

	return instruction.New(opInfo, data), nil
}