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 }
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 }