예제 #1
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
}
예제 #2
0
func (this Set) GetInstructionFromBytes(bytes []byte) (*instruction.Instruction, error) {

	if len(bytes) != 4 {
		return nil, errors.New(fmt.Sprintf("Expecting 4 bytes and got %d", len(bytes)))
	}

	value := uint32(bytes[0])<<24 + uint32(bytes[1])<<16 + uint32(bytes[2])<<8 + uint32(bytes[3])
	opcode := data.GetOpcodeFromUint32(value)

	// Search opcode in the instruction set
	info, err := this.GetInstructionInfoFromOpcode(opcode)
	if err != nil {
		return nil, err
	}

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

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