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 }