/ src / exec / shift.c
shift.c
  1  /*
  2   *  Bean Java VM
  3   *  Copyright (C) 2005-2015 Christian Lins <christian@lins.me>
  4   *
  5   *  Licensed under the Apache License, Version 2.0 (the "License");
  6   *  you may not use this file except in compliance with the License.
  7   *  You may obtain a copy of the License at
  8   *
  9   *     http://www.apache.org/licenses/LICENSE-2.0
 10   *
 11   *  Unless required by applicable law or agreed to in writing, software
 12   *  distributed under the License is distributed on an "AS IS" BASIS,
 13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14   *  See the License for the specific language governing permissions and
 15   *  limitations under the License.
 16   */
 17  
 18  #include <debug.h>
 19  #include <vm.h>
 20  
 21  void do_ISHL(Thread *thread)
 22  {
 23      dbgmsg("ISHL");
 24  
 25      int *value1;
 26      int *value2;
 27      Stackframe *frame = current_frame(thread);
 28  
 29      /* Retrieving values from operand stack */
 30      Stack_pop(&(frame->operandStack), (void **) &value2);
 31      value1 = (int *) frame->operandStack.top->data;
 32  
 33      /* Shifting n bits left, where n are the lower 5bits of value2 */
 34      *value1 = (*value1) << ((*value2) & 0x1F);
 35  
 36      /* As we're modifying the stack top directly, we do not need to push
 37       * the result back. But we should free value2. */
 38      free(value2);
 39  }
 40  
 41  void do_LSHL(Thread *thread)
 42  {
 43      dbgmsg("LSHL");
 44  
 45      int64_t *value1;
 46      int *value2;
 47      Stackframe *frame = current_frame(thread);
 48  
 49      /* Retrieving values from operand stack */
 50      Stack_pop(&(frame->operandStack), (void **) &value2);
 51      value1 = (int64_t *) frame->operandStack.top->data;
 52  
 53      /* Shifting n bits left, where n are the lower 6bits of value2 */
 54      *value1 = (*value1) << ((*value2) & 0x3F);
 55  
 56      /* As we're modifying the stack top directly, we do not need to push
 57       * the result back. But we should free value2. */
 58      free(value2);
 59  }
 60  
 61  void do_ISHR(Thread *thread)
 62  {
 63      dbgmsg("ISHR");
 64  
 65      int *value1;
 66      int *value2;
 67      Stackframe *frame = current_frame(thread);
 68  
 69      /* Retrieving values from operand stack */
 70      Stack_pop(&(frame->operandStack), (void **) &value2);
 71      value1 = (int *) frame->operandStack.top->data;
 72  
 73      /* Shifting n bits left, where n are the lower 5bits of value2 */
 74      *value1 = (*value1) >> ((*value2) & 0x1F);
 75  
 76      /* As we're modifying the stack top directly, we do not need to push
 77       * the result back. But we should free value2. */
 78      free(value2);
 79  }
 80  
 81  void do_LSHR(Thread *thread)
 82  {
 83      dbgmsg("LSHR");
 84  
 85      int64_t *value1;
 86      int *value2;
 87      Stackframe *frame = current_frame(thread);
 88  
 89      /* Retrieving values from operand stack */
 90      Stack_pop(&(frame->operandStack), (void **) &value2);
 91      value1 = (int64_t *) frame->operandStack.top->data;
 92  
 93      /* Shifting n bits left, where n are the lower 6bits of value2 */
 94      *value1 = (*value1) >> ((*value2) & 0x3F);
 95  
 96      /* As we're modifying the stack top directly, we do not need to push
 97       * the result back. But we should free value2. */
 98      free(value2);
 99  }
100  
101  /* Logical shift right */
102  void do_IUSHR(Thread *thread)
103  {
104      dbgmsg("IUSHR");
105  
106      int *value1;
107      int *value2;
108      Stackframe *frame = current_frame(thread);
109  
110      /* Retrieving values from operand stack */
111      Stack_pop(&(frame->operandStack), (void **) &value2);
112      value1 = (int *) frame->operandStack.top->data;
113  
114      if (*value1 > 0) {
115          *value1 = (*value1) >> (*value2 & 0x1F);
116      } else if (*value1 < 0) {
117          *value1 = (*value1 >> (*value2 & 0x1F)) + (2 << ~(*value2 & 0x1F));
118      }
119  
120      /* As we're modifying the stack top directly, we do not need to push
121       * the result back. But we should free value2. */
122      free(value2);
123  }
124  
125  /* Logical shift right */
126  void do_LUSHR(Thread *thread)
127  {
128      dbgmsg("LUSHR");
129  
130      int64_t *value1;
131      int *value2;
132      Stackframe *frame = current_frame(thread);
133  
134      /* Retrieving values from operand stack */
135      Stack_pop(&(frame->operandStack), (void **) &value2);
136      value1 = (int64_t *) frame->operandStack.top->data;
137  
138      if (*value1 > 0) {
139          *value1 = (*value1) >> (*value2 & 0x3F);
140      } else if (*value1 < 0) {
141          *value1 = (*value1 >> (*value2 & 0x3F)) + (2 << ~(*value2 & 0x3F));
142      }
143  
144      /* As we're modifying the stack top directly, we do not need to push
145       * the result back. But we should free value2. */
146      free(value2);
147  }