summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1999-09-08 20:25:12 +0000
committerGurusamy Sarathy <gsar@cpan.org>1999-09-08 20:25:12 +0000
commit4b4bcab6dfeacd5cae090d62c2aab79d4ab46e5d (patch)
treedd2bea83b4bf0dcc94d23cee1ab1ed8b0b3ec5ad /pp.c
parentabff13bb6f4392604279f83cbed17a9d16ae2d8f (diff)
parent26b44a0af0ea323b1f08d11d9890b96d19caeab9 (diff)
downloadperl-4b4bcab6dfeacd5cae090d62c2aab79d4ab46e5d.tar.gz
integrate cfgperl contents into mainline
p4raw-id: //depot/perl@4106
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c115
1 files changed, 87 insertions, 28 deletions
diff --git a/pp.c b/pp.c
index 23510ebbbb..6b71e8c883 100644
--- a/pp.c
+++ b/pp.c
@@ -28,6 +28,37 @@ static double UV_MAX_cxux = ((double)UV_MAX);
#endif
/*
+ * Types used in bitwise operations.
+ *
+ * Normally we'd just use IV and UV. However, some hardware and
+ * software combinations (e.g. Alpha and current OSF/1) don't have a
+ * floating-point type to use for NV that has adequate bits to fully
+ * hold an IV/UV. (In other words, sizeof(long) == sizeof(double).)
+ *
+ * It just so happens that "int" is the right size almost everywhere.
+ */
+typedef int IBW;
+typedef unsigned UBW;
+
+/*
+ * Mask used after bitwise operations.
+ *
+ * There is at least one realm (Cray word machines) that doesn't
+ * have an integral type (except char) small enough to be represented
+ * in a double without loss; that is, it has no 32-bit type.
+ */
+#if LONGSIZE > 4 && defined(_CRAY) && !defined(_CRAYMPP)
+# define BW_BITS 32
+# define BW_MASK ((1 << BW_BITS) - 1)
+# define BW_SIGN (1 << (BW_BITS - 1))
+# define BWi(i) (((i) & BW_SIGN) ? ((i) | ~BW_MASK) : ((i) & BW_MASK))
+# define BWu(u) ((u) & BW_MASK)
+#else
+# define BWi(i) (i)
+# define BWu(u) (u)
+#endif
+
+/*
* Offset for integer pack/unpack.
*
* On architectures where I16 and I32 aren't really 16 and 32 bits,
@@ -1102,11 +1133,17 @@ PP(pp_left_shift)
{
djSP; dATARGET; tryAMAGICbin(lshift,opASSIGN);
{
- IV shift = POPi;
- if (PL_op->op_private & HINT_INTEGER)
- SETi(TOPi << shift);
- else
- SETu(TOPu << shift);
+ IBW shift = POPi;
+ if (PL_op->op_private & HINT_INTEGER) {
+ IBW i = TOPi;
+ i = BWi(i) << shift;
+ SETi(BWi(i));
+ }
+ else {
+ UBW u = TOPu;
+ u <<= shift;
+ SETu(BWu(u));
+ }
RETURN;
}
}
@@ -1115,11 +1152,17 @@ PP(pp_right_shift)
{
djSP; dATARGET; tryAMAGICbin(rshift,opASSIGN);
{
- IV shift = POPi;
- if (PL_op->op_private & HINT_INTEGER)
- SETi(TOPi >> shift);
- else
- SETu(TOPu >> shift);
+ IBW shift = POPi;
+ if (PL_op->op_private & HINT_INTEGER) {
+ IBW i = TOPi;
+ i = BWi(i) >> shift;
+ SETi(BWi(i));
+ }
+ else {
+ UBW u = TOPu;
+ u >>= shift;
+ SETu(BWu(u));
+ }
RETURN;
}
}
@@ -1287,10 +1330,14 @@ PP(pp_bit_and)
{
dPOPTOPssrl;
if (SvNIOKp(left) || SvNIOKp(right)) {
- if (PL_op->op_private & HINT_INTEGER)
- SETi( SvIV(left) & SvIV(right) );
- else
- SETu( SvUV(left) & SvUV(right) );
+ if (PL_op->op_private & HINT_INTEGER) {
+ IBW value = SvIV(left) & SvIV(right);
+ SETi(BWi(value));
+ }
+ else {
+ UBW value = SvUV(left) & SvUV(right);
+ SETu(BWu(value));
+ }
}
else {
do_vop(PL_op->op_type, TARG, left, right);
@@ -1306,10 +1353,14 @@ PP(pp_bit_xor)
{
dPOPTOPssrl;
if (SvNIOKp(left) || SvNIOKp(right)) {
- if (PL_op->op_private & HINT_INTEGER)
- SETi( (USE_LEFT(left) ? SvIV(left) : 0) ^ SvIV(right) );
- else
- SETu( (USE_LEFT(left) ? SvUV(left) : 0) ^ SvUV(right) );
+ if (PL_op->op_private & HINT_INTEGER) {
+ IBW value = (USE_LEFT(left) ? SvIV(left) : 0) ^ SvIV(right);
+ SETi(BWi(value));
+ }
+ else {
+ UBW value = (USE_LEFT(left) ? SvUV(left) : 0) ^ SvUV(right);
+ SETu(BWu(value));
+ }
}
else {
do_vop(PL_op->op_type, TARG, left, right);
@@ -1325,10 +1376,14 @@ PP(pp_bit_or)
{
dPOPTOPssrl;
if (SvNIOKp(left) || SvNIOKp(right)) {
- if (PL_op->op_private & HINT_INTEGER)
- SETi( (USE_LEFT(left) ? SvIV(left) : 0) | SvIV(right) );
- else
- SETu( (USE_LEFT(left) ? SvUV(left) : 0) | SvUV(right) );
+ if (PL_op->op_private & HINT_INTEGER) {
+ IBW value = (USE_LEFT(left) ? SvIV(left) : 0) | SvIV(right);
+ SETi(BWi(value));
+ }
+ else {
+ UBW value = (USE_LEFT(left) ? SvUV(left) : 0) | SvUV(right);
+ SETu(BWu(value));
+ }
}
else {
do_vop(PL_op->op_type, TARG, left, right);
@@ -1387,10 +1442,14 @@ PP(pp_complement)
{
dTOPss;
if (SvNIOKp(sv)) {
- if (PL_op->op_private & HINT_INTEGER)
- SETi( ~SvIV(sv) );
- else
- SETu( ~SvUV(sv) );
+ if (PL_op->op_private & HINT_INTEGER) {
+ IBW value = ~SvIV(sv);
+ SETi(BWi(value));
+ }
+ else {
+ UBW value = ~SvUV(sv);
+ SETu(BWu(value));
+ }
}
else {
register char *tmps;
@@ -1719,9 +1778,9 @@ S_seed(pTHX)
# endif
#endif
u += SEED_C3 * (U32)getpid();
- u += SEED_C4 * (U32)(UV)PL_stack_sp;
+ u += SEED_C4 * (U32)(UV)PTR_CAST PL_stack_sp;
#ifndef PLAN9 /* XXX Plan9 assembler chokes on this; fix needed */
- u += SEED_C5 * (U32)(UV)&when;
+ u += SEED_C5 * (U32)(UV)PTR_CAST &when;
#endif
return u;
}