#    This file is part of Metasm, the Ruby assembly manipulation suite
#    Copyright (C) 2006-2009 Yoann GUILLOT
#
#    Licence is LGPL, see LICENCE in the top-level directory


require 'metasm/cpu/mips/opcodes'
require 'metasm/parse'

module Metasm
class MIPS
	def parse_arg_valid?(op, sym, arg)
		# special case for lw reg, imm32(reg) ? (pseudo-instr, need to convert to 'lui t0, up imm32  ori t0 down imm32  add t0, reg  lw reg, 0(t0)
		case sym
		when :rs, :rt, :rd;   arg.kind_of? Reg
		when :sa, :i16, :i20, :i26; arg.kind_of? Expression
		when :rs_i16;         arg.kind_of? Memref
		when :ft;             arg.kind_of? FpReg
		else raise "internal error: mips arg #{sym.inspect}"
		end
	end

	def parse_argument(pgm)
		pgm.skip_space
		return if not tok = pgm.nexttok
		if tok.type == :string and Reg.s_to_i[tok.raw]
			pgm.readtok
			arg = Reg.new Reg.s_to_i[tok.raw]
		elsif tok.type == :string and FpReg.s_to_i[tok.raw]
			pgm.readtok
			arg = FpReg.new FpReg.s_to_i[tok.raw]
		else
			arg = Expression.parse pgm
			pgm.skip_space
			# check memory indirection: 'off(base reg)'	# XXX scaled index ?
			if arg and pgm.nexttok and pgm.nexttok.type == :punct and pgm.nexttok.raw == '('
				pgm.readtok
				pgm.skip_space_eol
				ntok = pgm.readtok
				raise tok, "Invalid base #{ntok}" unless ntok and ntok.type == :string and Reg.s_to_i[ntok.raw]
				base = Reg.new Reg.s_to_i[ntok.raw]
				pgm.skip_space_eol
				ntok = pgm.readtok
				raise tok, "Invalid memory reference, ')' expected" if not ntok or ntok.type != :punct or ntok.raw != ')'
				arg = Memref.new base, arg
			end
		end
		arg
	end
end
end
