From b9e93a983209e6ea5d4ebba13c670818dfdf7e6c Mon Sep 17 00:00:00 2001 From: inglorion Date: Sat, 8 Jan 2011 10:59:55 +0100 Subject: [PATCH] Implemented shift actions for i386 and AMD64 --- lib/voodoo/generators/common_code_generator.rb | 4 ++++ lib/voodoo/generators/nasm_generator.rb | 30 +++++++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/voodoo/generators/common_code_generator.rb b/lib/voodoo/generators/common_code_generator.rb index 65e2116..627c934 100644 --- a/lib/voodoo/generators/common_code_generator.rb +++ b/lib/voodoo/generators/common_code_generator.rb @@ -55,6 +55,8 @@ module Voodoo # of the following methods, which must be implemented by subclasses: # # - #align + # - #asr + # - #bsr # - #byte # - #call # - #end_if @@ -75,6 +77,8 @@ module Voodoo # - #set # - #set_byte # - #set_word + # - #shl + # - #shr # - #string # - #word # diff --git a/lib/voodoo/generators/nasm_generator.rb b/lib/voodoo/generators/nasm_generator.rb index c157b56..5b45a9e 100644 --- a/lib/voodoo/generators/nasm_generator.rb +++ b/lib/voodoo/generators/nasm_generator.rb @@ -224,7 +224,8 @@ module Voodoo # Test if op is a binary operation def binop? op - [:div, :mod, :sub].member?(op) || symmetric_operation?(op) + [:asr, :bsr, :div, :mod, :shl, :shr, :sub].member?(op) || + symmetric_operation?(op) end # Test if a value is an integer @@ -452,14 +453,15 @@ module Voodoo x_ref = load_value x, @DX y_ref = load_value y, @BX + mnemonic = action_to_mnemonic op if memory_operand?(target_ref) if memory_operand?(x_ref) || memory_operand?(y_ref) emit "mov #{@CX}, #{x_ref}\n" - emit "#{op} #{@CX}, #{y_ref}\n" + emit "#{mnemonic} #{@CX}, #{y_ref}\n" emit "mov #{target_ref}, #{@CX}\n" else emit "mov #{@WORD_NAME} #{target_ref}, #{x_ref}\n" - emit "#{op} #{@WORD_NAME} #{target_ref}, #{y_ref}\n" + emit "#{mnemonic} #{@WORD_NAME} #{target_ref}, #{y_ref}\n" end else raise "Can't happen: target_ref is #{target_ref.inspect}" @@ -477,11 +479,12 @@ module Voodoo target_ref = load_value target, @BX y_ref = load_value y, @DX + mnemonic = action_to_mnemonic op if memory_operand?(target_ref) && memory_operand?(y_ref) emit "mov #{@AX}, #{y_ref}\n" - emit "#{op} #{target_ref}, #{@AX}\n" + emit "#{mnemonic} #{target_ref}, #{@AX}\n" else - emit "#{op} #{@WORD_NAME} #{target_ref}, #{y_ref}\n" + emit "#{mnemonic} #{@WORD_NAME} #{target_ref}, #{y_ref}\n" end end @@ -542,6 +545,7 @@ module Voodoo # Evaluate an expression. # The result is stored in _register_ (@RETURN_REG by default). + # The following registers may be clobbered: @AX, @BX, @CX, @DX def eval_expr words, register = @RETURN_REG if words.length == 1 if words[0] == 0 @@ -552,6 +556,10 @@ module Voodoo else op = words[0] case op + when :asr, :bsr, :shl, :shr + load_value_into_register words[2], @CX + load_value_into_register words[1], register + emit "#{action_to_mnemonic op} #{register}, cl\n" when :call call *words[1..-1] when :div @@ -698,6 +706,18 @@ module Voodoo # == Miscellaneous # + # Translates a Voodoo action name to an x86 mnemonic + def action_to_mnemonic action + case action + when :asr + :sar + when :bsr + :shr + else + action + end + end + # Emit a comment def comment text emit ";#{text}\n" -- 2.11.4.GIT