00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 # include "incls/_precompiled.incl"
00026 # include "incls/_smi_prims.cpp.incl"
00027
00028 TRACE_FUNC(TraceSmiPrims, "smi")
00029
00030 int smiOopPrimitives::number_of_calls;
00031
00032 # define ASSERT_RECEIVER assert(receiver->is_smi(), "receiver must be smi")
00033
00034 # define SMI_RELATIONAL_OP(op) \
00035 if (!argument->is_smi()) \
00036 return markSymbol(vmSymbols::first_argument_has_wrong_type()); \
00037 int a = (int) receiver; \
00038 int b = (int) argument; \
00039 return a op b ? trueObj : falseObj
00040
00041 PRIM_DECL_2(smiOopPrimitives::lessThan, oop receiver, oop argument) {
00042 PROLOGUE_2("lessThan", receiver, argument);
00043 ASSERT_RECEIVER;
00044 SMI_RELATIONAL_OP(<);
00045 }
00046
00047 PRIM_DECL_2(smiOopPrimitives::greaterThan, oop receiver, oop argument){
00048 PROLOGUE_2("greaterThan", receiver, argument);
00049 ASSERT_RECEIVER;
00050 SMI_RELATIONAL_OP(>);
00051 }
00052
00053 PRIM_DECL_2(smiOopPrimitives::lessThanOrEqual, oop receiver, oop argument) {
00054 PROLOGUE_2("lessThanOrEqual", receiver, argument);
00055 ASSERT_RECEIVER;
00056 SMI_RELATIONAL_OP(<=);
00057 }
00058
00059 PRIM_DECL_2(smiOopPrimitives::greaterThanOrEqual, oop receiver, oop argument) {
00060 PROLOGUE_2("greaterThanOrEqual", receiver, argument);
00061 ASSERT_RECEIVER;
00062 SMI_RELATIONAL_OP(>=);
00063 }
00064
00065 PRIM_DECL_2(smiOopPrimitives::equal, oop receiver, oop argument) {
00066 PROLOGUE_2("equal", receiver, argument);
00067 ASSERT_RECEIVER;
00068 SMI_RELATIONAL_OP(==);
00069 }
00070
00071 PRIM_DECL_2(smiOopPrimitives::notEqual, oop receiver, oop argument) {
00072 PROLOGUE_2("notEqual", receiver, argument);
00073 ASSERT_RECEIVER;
00074 SMI_RELATIONAL_OP(!=);
00075 }
00076
00077 PRIM_DECL_2(smiOopPrimitives::bitAnd, oop receiver, oop argument) {
00078 PROLOGUE_2("bitAnd", receiver, argument);
00079 ASSERT_RECEIVER;
00080 if (!argument->is_smi())
00081 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00082 return smiOop(int(receiver) & int(argument));
00083 }
00084
00085 PRIM_DECL_2(smiOopPrimitives::bitOr, oop receiver, oop argument) {
00086 PROLOGUE_2("bitOr", receiver, argument);
00087 ASSERT_RECEIVER;
00088 if (!argument->is_smi())
00089 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00090 return smiOop(int(receiver) | int(argument));
00091 }
00092
00093 PRIM_DECL_2(smiOopPrimitives::bitXor, oop receiver, oop argument) {
00094 PROLOGUE_2("bitXor", receiver, argument);
00095 ASSERT_RECEIVER;
00096 if (!argument->is_smi())
00097 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00098 return smiOop(int(receiver) ^ int(argument));
00099 }
00100
00101 PRIM_DECL_2(smiOopPrimitives::bitShift, oop receiver, oop argument) {
00102 PROLOGUE_2("bitShift", receiver, argument);
00103 ASSERT_RECEIVER;
00104 if (!argument->is_smi())
00105 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00106 assert(Int_Tag == 0, "check this code");
00107 const int bitsPerWord = oopSize*8;
00108 const int maxShiftCnt = bitsPerWord - Tag_Size - 1;
00109 int n = smiOop(argument)->value();
00110 if (n > 0) {
00111
00112 if (n < maxShiftCnt) {
00113
00114 int mask1 = 1 << (bitsPerWord - (n+1));
00115 int mask2 = -1 << (bitsPerWord - n);
00116 if (((int(receiver) + mask1) & mask2) == 0) {
00117
00118
00119 return smiOop(int(receiver) << n);
00120 }
00121 }
00122 return vmSymbols::smi_overflow();
00123 } else {
00124
00125 if (n < -maxShiftCnt) n = -maxShiftCnt;
00126 return smiOop((int(receiver) >> -n) & (-1 << Tag_Size));
00127 }
00128 }
00129
00130 PRIM_DECL_2(smiOopPrimitives::rawBitShift, oop receiver, oop argument) {
00131 PROLOGUE_2("rawBitShift", receiver, argument);
00132 ASSERT_RECEIVER;
00133 if (!argument->is_smi())
00134 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00135 assert(Int_Tag == 0, "check this code");
00136 const int bitsPerWord = oopSize*8;
00137 int n = smiOop(argument)->value();
00138 if (n >= 0) {
00139
00140 return smiOop((unsigned int)receiver << (n % bitsPerWord));
00141 } else {
00142
00143 return smiOop(((unsigned int)receiver >> ((-n) % bitsPerWord)) & (-1 << Tag_Size));
00144 }
00145 }
00146
00147 PRIM_DECL_1(smiOopPrimitives::asObject, oop receiver) {
00148 PROLOGUE_1("asObject", receiver);
00149 ASSERT_RECEIVER;
00150 int id = smiOop(receiver)->value();
00151 if (objectIDTable::is_index_ok(id))
00152 return objectIDTable::at(id);
00153 return markSymbol(vmSymbols::index_not_valid());
00154 }
00155
00156 PRIM_DECL_1(smiOopPrimitives::printCharacter, oop receiver) {
00157 PROLOGUE_1("printCharacter", receiver);
00158 ASSERT_RECEIVER;
00159 lprintf("%c", smiOop(receiver)->value());
00160 return receiver;
00161 }